paint-brush
Manifold가 Java에서 JSON 구문 분석을 혁신하는 방법~에 의해@shai.almog
893 판독값
893 판독값

Manifold가 Java에서 JSON 구문 분석을 혁신하는 방법

~에 의해 Shai Almog8m2023/05/02
Read on Terminal Reader
Read this story w/o Javascript

너무 오래; 읽다

Java(및 기타 형식)에서 JSON을 구문 분석하는 것은 JavaScript만큼 쉬울 수 있습니다. 유형 안전성과 심층적인 IDE 통합을 유지하면서 훨씬 더 많은 작업을 수행할 수 있습니다.
featured image - Manifold가 Java에서 JSON 구문 분석을 혁신하는 방법
Shai Almog HackerNoon profile picture

Java 개발자는 JSON을 쉽게 구문 분석할 수 있는 JavaScript를 부러워하는 경우가 많습니다. Java는 더 강력함을 제공하지만 더 많은 작업과 상용구 코드가 필요한 경향이 있습니다. Manifold 프로젝트 덕분에 Java는 이제 JSON 파일을 구문 분석하고 처리하는 데 있어서 JavaScript를 능가할 수 있는 잠재력을 갖게 되었습니다.


Manifold는 JSON을 처리하는 방식을 완전히 바꾸는 혁신적인 Java용 언어 확장 세트입니다.

매니폴드 시작하기

이 튜토리얼의 코드는 내 GitHub 페이지 에서 찾을 수 있습니다. 매니폴드는 상대적으로 젊지만 그 능력은 이미 방대합니다. 웹사이트와 Slack 채널에서 프로젝트에 대해 자세히 알아볼 수 있습니다.


시작하려면 현재 JetBrains IDE에서만 사용할 수 있는 Manifold 플러그인을 설치해야 합니다. 이 프로젝트는 최신 JDK 19를 포함하여 Java의 LTS 릴리스를 지원합니다.


마켓플레이스로 이동하고 Manifold를 검색하여 IntelliJ/IDEAs 설정 UI에서 플러그인을 설치할 수 있습니다. 플러그인은 IDE가 Maven/Gradle 플러그인이 수행한 작업과 충돌하지 않도록 합니다.

이미지 설명

Manifold는 각각 사용자 정의 언어 확장을 제공하는 여러 개의 소규모 프로젝트로 구성됩니다. 오늘 우리는 그러한 확장 중 하나에 대해 논의할 것이지만, 탐구할 것이 훨씬 더 많습니다.

Maven 프로젝트 설정

Manifold를 시연하기 위해 간단한 Maven 프로젝트를 사용하겠습니다(Gradle에서도 작동함). 먼저 웹사이트에서 현재 Manifold 버전을 붙여넣고 필요한 종속성을 추가해야 합니다. JSON의 주요 종속성은 manifold-json-rt 종속성입니다.


YAML, XML 및 CSV 지원을 위해 다른 종속성을 추가할 수 있습니다. 이를 프로젝트의 pom.xml 파일에 추가해야 합니다.


저는 JSON에 대한 상용구 감소가 Maven 빌드 스크립트의 많은 구성으로 시작된다는 아이러니를 알고 있습니다. 그러나 이는 "실제 코드"가 아닌 구성입니다. 대부분 복사 & 붙여넣기 입니다.


이 코드를 줄이려는 경우 Gradle에 해당하는 코드는 비교하면 간결합니다.


이 줄은 속성 섹션으로 이동해야 합니다.

 <manifold.version>2023.1.5</manifold.version>


우리가 사용하는 종속성은 다음과 같습니다.

 <dependencies>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-json-rt</artifactId>       <version>${manifold.version}</version>   </dependency>


컴파일 플러그인은 Manifold를 바이트코드로 엮어 원활하게 만드는 상용구입니다. pom 설정의 마지막 부분입니다.

 <build>   <plugins>       <plugin>           <groupId>org.apache.maven.plugins</groupId>           <artifactId>maven-compiler-plugin</artifactId>           <version>3.8.0</version>           <configuration>               <source>19</source>               <target>19</target>               <encoding>UTF-8</encoding>               <compilerArgs>                   <!-- Configure manifold plugin-->                   <arg>-Xplugin:Manifold</arg>               </compilerArgs>               <!-- Add the processor path for the plugin -->               <annotationProcessorPaths>                   <path>                       <groupId>systems.manifold</groupId>                       <artifactId>manifold-json</artifactId>                       <version>${manifold.version}</version>                   </path>               </annotationProcessorPaths>           </configuration>       </plugin>   </plugins> </build>

설정이 완료되었으면 코드를 살펴보겠습니다.

매니폴드를 사용하여 JSON 구문 분석

리소스 계층 구조 아래의 프로젝트 디렉터리에 샘플 JSON 파일을 배치합니다. 이 파일을 src/main/resources/com/debugagent/json/Test.json 아래에 배치했습니다.

 { "firstName": "Shai", "surname": "Almog", "website": "https://debugagent.com/", "active": true, "details":[ {"key": "value"} ] }


메인 클래스에서 Maven 프로젝트를 새로 고치면 새로운 Test 클래스가 나타나는 것을 볼 수 있습니다. 이 클래스는 JSON 파일을 기반으로 Manifold에 의해 동적으로 생성됩니다. JSON을 변경하고 Maven을 새로 고치면 모든 것이 원활하게 업데이트됩니다.


Manifold는 코드 생성기가 아니라는 점을 이해하는 것이 중요합니다. 방금 작성한 JSON을 바이트코드로 컴파일합니다.


Test 클래스에는 빌더 메소드를 사용하여 JSON 객체를 구성할 수 있는 유형 안전 빌더 API와 같은 여러 내장 기능이 함께 제공됩니다. write()toJson() 메서드를 사용하여 중첩 개체를 생성하고 JSON을 문자열로 변환할 수도 있습니다.


이는 이제 다음과 같이 작성할 수 있음을 의미합니다.

 Test test = Test.builder().withFirstName("Someone") .withSurname("Surname") .withActive(true) .withDetails(List.of( Test.details.detailsItem.builder(). withKey("Value 1").build() )) .build();


다음 JSON이 인쇄됩니다.

 {  "firstName": "Someone",  "surname": "Surname",  "active": true,  "details": [    {      "key": "Value 1"    }  ] }


다음과 같은 코드를 사용하여 JSON 파일을 유사하게 읽을 수 있습니다.

 Test readObject = Test.load().fromJson(""" { "firstName": "Someone", "surname": "Surname", "active": true, "details": [ { "key": "Value 1" } ] } """);


긴 문자열을 작성하기 위해 Java 15 TextBlock 구문을 사용하는 것에 유의하세요. load() 메서드는 JSON을 읽기 위한 다양한 API가 포함된 객체를 반환합니다. 이 경우 String 에서 읽히지만 URL, 파일 등에서 읽는 API가 있습니다.


Manifold는 CSV, XML 및 YAML을 포함한 다양한 형식을 지원하므로 상용구 코드를 작성하거나 유형 안전성을 희생하지 않고도 이러한 형식을 생성하고 구문 분석할 수 있습니다. 해당 지원을 추가하려면 pom.xml 파일에 추가 종속성을 추가해야 합니다.

   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-csv-rt</artifactId>       <version>${manifold.version}</version>   </dependency>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-xml-rt</artifactId>       <version>${manifold.version}</version>   </dependency>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-yaml-rt</artifactId>       <version>${manifold.version}</version>   </dependency> </dependencies>


이러한 추가 종속성을 사용하면 이 코드는 JSON 파일과 동일한 데이터를 인쇄합니다... test.write().toCsv() 사용하면 출력은 다음과 같습니다.

 "firstName","surname","active","details" "Someone","Surname","true","[manifold.json.rt.api.DataBindings@71070b9c]"


CSV(쉼표로 구분된 값) 출력에는 계층 구조 정보가 포함되지 않습니다. 이는 Manifold의 결함이 아니라 CSV 형식의 제한 사항입니다.


test.write().toXml() 사용하면 출력이 친숙하고 놀라울 정도로 간결합니다.

 <root_object firstName="Someone" surname="Surname" active="true">  <details key="Value 1"/> </root_object>


test.write().toYaml() 사용하면 다시 익숙한 출력 결과를 얻을 수 있습니다.

 firstName: Someone surname: Surname active: true details: - key: Value 1

JSON 스키마 작업

Manifold는 또한 JSON 스키마와 원활하게 작동하므로 엄격한 규칙과 제약 조건을 적용할 수 있습니다. 이는 날짜와 열거형으로 작업할 때 특히 유용합니다.


Manifold는 스키마를 준수하는 바이트 코드를 원활하게 생성/업데이트하므로 복잡한 JSON 데이터 작업이 훨씬 쉬워집니다.


이 스키마는 Manifold GitHub 프로젝트 에서 복사하여 붙여넣습니다.

 { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/schemas/User.json", "type": "object", "definitions": { "Gender": { "type": "string", "enum": ["male", "female"] } }, "properties": { "name": { "type": "string", "description": "User's full name.", "maxLength": 80 }, "email": { "description": "User's email.", "type": "string", "format": "email" }, "date_of_birth": { "type": "string", "description": "Date of uses birth in the one and only date standard: ISO 8601.", "format": "date" }, "gender": { "$ref" : "#/definitions/Gender" } }, "required": ["name", "email"] }


비교적 간단한 스키마이지만 여기서는 몇 가지 사항에 주목하고 싶습니다. 필요에 따라 이름과 이메일을 정의합니다. 이것이 바로 Manifold의 빌더를 사용하여 User 개체를 생성하려고 할 때 build() 메서드에 두 매개변수가 모두 필요한 이유입니다.

 User.builder("Name", "[email protected]")


그것은 단지 시작일 뿐입니다... 스키마에는 날짜가 포함되어 있습니다. 날짜는 JSON에서 골치 아픈 전망이며 표준화가 열악하고 문제가 많습니다. 스키마에는 사실상 열거형인 성별 필드도 포함되어 있습니다.


이는 모두 LocalDate와 같은 일반적인 Java 클래스를 사용하여 유형이 안전한 의미 체계로 변환됩니다.

 User u = User.builder("Name", "[email protected]")       .withDate_of_birth(LocalDate.of(1999, 10, 11))       .withGender(User.Gender.male)       .build();


정적 가져오기를 사용하면 더 짧게 만들 수 있지만 아이디어의 요점은 분명합니다. JSON은 사실상 Manifold의 Java에 기본입니다.

빙산의 일각

Manifold는 강력하고 흥미로운 프로젝트입니다. 이는 Java에서 JSON 구문 분석에 혁명을 일으켰지만 이는 이것이 수행할 수 있는 작업 중 극히 일부일 뿐입니다!


우리는 이 게시물에서 그 기능의 표면만을 긁어보았습니다. 다음 기사에서는 Manifold에 대해 더 자세히 알아보고 몇 가지 예상치 못한 추가 기능을 살펴보겠습니다.


댓글 섹션에서 Manifold에 대한 경험과 생각을 공유해 주세요. 궁금한 점이 있으면 주저하지 말고 문의하세요.