JavaRush /Java Blog /Random-KO /Json 구성표: 왜 그리고 누가 필요합니까?

Json 구성표: 왜 그리고 누가 필요합니까?

Random-KO 그룹에 게시되었습니다
안녕하세요, 방랑자님. 오늘은 작은 마술에 대해 말씀드리고 싶습니다. 아마도 json에 대해 이미 들어보셨을 것입니다. 이것은 매우 보편적인 언어입니다. 기계가 이해하고 인간이 쉽게 읽을 수 있습니다. 다음은 json 메시지의 일반적인 예입니다.
{
   "помещение":{
      "название":"избушка",
      "разумна":true
   },
   "основание":{
      "тип":"курьи ноги",
      "количество":2
   },
   "проживающие":[
      {
         "Name":"Баба Яга",
         "профиль":"ведьма"
      }
   ],
   "местоположение":{
      "address":"граница леса"
   }
}
그렇게 소통하면 편하지 않나요? 이전에 json이 무엇인지 몰랐다면 이제는 알 수 있습니다. Java 코드에서 이것을 어떻게 사용합니까? Json은 범용 형식이 되었습니다. JavaScript Object Notation의 약자이지만 오랫동안 javascript를 넘어 거의 모든 곳에서 사용되었습니다. Java에는 json 작업을 더 쉽게 해주는 여러 라이브러리가 있습니다. 가장 유명한 것은 다음과 같습니다. 저는 두 번째 것을 사용하겠습니다. 두 가지 버전이 있습니다 : codehausfastxml . 차이점을 발견하지 못했으므로 여기에서는 어느 버전이든 사용할 수 있습니다. 다음은 코드입니다.
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue("сюда json", "сюда класс");
json을 객체로 변환하는 데 도움이 됩니다. 그리고 우리는 가장 중요한 것에 접근하고 있습니다. 이 json에 대한 클래스를 작성합니다. 이 작업을 수동으로 수행할 수 있으며 다음과 같은 구조를 생성할 수 있습니다.
-----------------------------------com.fairytale.Base.java-----------------------------------

package com.fairytale;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;


@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"type",
"quantity"
})
public class Base {

@JsonProperty("type")
public String type = "";
@JsonProperty("quantity")
public int quantity = 0;

}
-----------------------------------com.fairytale.Hut.java-----------------------------------

package com.fairytale;

import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;


@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"room",
"base",
"residents",
"location"
})
public class Hut {

@JsonProperty("room")
public Room room;
@JsonProperty("base")
public Base base;
@JsonProperty("residents")
public List<Resident> residents = new ArrayList<Resident>();
@JsonProperty("location")
public Location location;

}
-----------------------------------com.fairytale.Location.java-----------------------------------

package com.fairytale;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;


@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"address"
})
public class Location {

@JsonProperty("address")
public String address = "";

}
-----------------------------------com.fairytale.Resident.java-----------------------------------

package com.fairytale;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;


@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"name",
"profile"
})
public class Resident {

@JsonProperty("name")
public String name = "";
@JsonProperty("profile")
public String profile = "";

}
-----------------------------------com.fairytale.Room.java-----------------------------------

package com.fairytale;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"name",
"reasonable"
})
public class Room {

@JsonProperty("name")
public String name = "";
@JsonProperty("reasonable")
public boolean reasonable = false;

}
특별히 getter, setter, 생성자 및 기타 pojo 속성을 생략했습니다. 그렇지 않으면 낭비에 지쳤을 것입니다 =) 이제 여기를 보십시오:
{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "room",
    "base",
    "residents",
    "location"
  ],
  "properties": {
    "room": {
      "$id": "#/properties/room",
      "type": "object",
      "title": "The Room Schema",
      "required": [
        "name",
        "reasonable"
      ],
      "properties": {
        "name": {
          "$id": "#/properties/room/properties/name",
          "type": "string",
          "title": "The Name Schema",
          "default": "",
          "examples": [
            "избушка"
          ],
          "pattern": "^(.*)$"
        },
        "reasonable": {
          "$id": "#/properties/room/properties/reasonable",
          "type": "boolean",
          "title": "The Reasonable Schema",
          "default": false,
          "examples": [
            true
          ]
        }
      },
	"additionalProperties": false
    },
    "base": {
      "$id": "#/properties/base",
      "type": "object",
      "title": "The Base Schema",
      "required": [
        "type",
        "quantity"
      ],
      "properties": {
        "type": {
          "$id": "#/properties/base/properties/type",
          "type": "string",
          "title": "The Type Schema",
          "default": "",
          "examples": [
            "курьи ноги"
          ],
          "pattern": "^(.*)$"
        },
        "quantity": {
          "$id": "#/properties/base/properties/quantity",
          "type": "integer",
          "title": "The Quantity Schema",
          "default": 0,
          "examples": [
            2
          ]
        }
      },
	"additionalProperties": false
    },
    "residents": {
      "$id": "#/properties/residents",
      "type": "array",
      "title": "The Residents Schema",
      "items": {
        "$id": "#/properties/residents/items",
        "type": "object",
        "title": "The Items Schema",
        "required": [
          "name",
          "profile"
        ],
        "properties": {
          "name": {
            "$id": "#/properties/residents/items/properties/name",
            "type": "string",
            "title": "The Name Schema",
            "default": "",
            "examples": [
              "Баба Яга"
            ],
            "pattern": "^(.*)$"
          },
          "profile": {
            "$id": "#/properties/residents/items/properties/profile",
            "type": "string",
            "title": "The Profile Schema",
            "default": "",
            "examples": [
              "ведьма"
            ],
            "pattern": "^(.*)$"
          }
        },
	    "additionalProperties": false
      }
    },
    "location": {
      "$id": "#/properties/location",
      "type": "object",
      "title": "The Location Schema",
      "required": [
        "address"
      ],
      "properties": {
        "address": {
          "$id": "#/properties/location/properties/address",
          "type": "string",
          "title": "The Address Schema",
          "default": "",
          "examples": [
            "граница леса"
          ],
          "pattern": "^(.*)$",
		  "additionalProperties": false
        }
      },
	"additionalProperties": false
    }
  },
	"additionalProperties": false
}
위 구조의 json 다이어그램은 다음과 같습니다. 이제 왜 필요한지 설명할 차례입니다. 클래스를 작성하고 유지 관리할 필요가 없어집니다. jsonschema2pojo 라는 좋은 프로젝트가 있습니다 . 빌드 시 이러한 클래스를 작성하는 프로젝트 빌더(Maven, Gradle)용 플러그인을 제공합니다. 내 프로젝트의 예는 다음과 같습니다.
<plugin>
    <groupId>org.jsonschema2pojo</groupId>
    <artifactId>jsonschema2pojo-maven-plugin</artifactId>
    <version>0.4.37</version>

    <executions>
        <execution>
            <id>jsonschema2opjo</id>
            <configuration>
                <sourceDirectory>${project.basedir}/src/main/resources/json-schema/</sourceDirectory>
                <targetPackage>tester.model</targetPackage>
                <outputDirectory>${project.basedir}/target/generated-sources/jsonschema/</outputDirectory>
                <useCommonsLang3>true</useCommonsLang3>
                <includeConstructors>true</includeConstructors>
                <generateBuilders>true</generateBuilders>
                <includeToString>true</includeToString>
                <usePrimitives>true</usePrimitives>
            </configuration>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>generate-sources</phase>
        </execution>
    </executions>
</plugin>
이것이 그의 설정입니다. 가장 흥미로운 점은 다음과 같습니다.
<useCommonsLang3>true</useCommonsLang3>
<includeConstructors>true</includeConstructors>
<generateBuilders>true</generateBuilders>
<includeToString>true</includeToString>
<usePrimitives>true</usePrimitives>
다음은 클래스 작성 방법에 대한 지침입니다. useCommonsLang3 - CommonsLang3 라이브러리 사용 includeConstructors - 생성자 작성 generateBuilders - 패턴 빌더 구축 includeToString - toString 추가 usePrimitives - 프리미티브 사용 지침 이것이 집에서 작성한 코드보다 나은 점 ?
  1. 한 줄로 수업을 맞춤 설정할 수 있습니다. 예를 들어 각 클래스에 Pojo 접미사를 추가해야 합니다. <classNameSuffix>Pojo</classNameSuffix>를 추가하여 프로젝트를 어셈블하면 완료됩니다. 그렇지 않으면 각 클래스의 이름을 수동으로 변경해야 합니다.

    이러한 매개변수가 많이 있으므로 문서 에서 이에 대해 모두 읽어 볼 가치가 있습니다.

  2. 프로젝트에 소비자가 있는 경우 Java 클래스보다 json 스키마를 제공하는 것이 훨씬 쉽습니다. 내가 이미 말했듯이, 계획은 보편적이며 소비자는 단순히 자신의 언어로 포조를 생성할 것입니다.

  3. 그들은 훨씬 작습니다. 위의 예시에는 패턴, 예시 등 항상 필요하지 않은 정보가 많이 포함되어 있습니다. 하지만 이를 자바 코드로 되돌리면 그 규모도 많이 늘어납니다. 그리고 플러그인의 몇 가지 설정을 통해 다이어그램에 표시되는 템플릿 코드를 잊지 마세요. 하지만 이를 코드에 직접 작성해야 합니다. 그리고 네, 저는 롬복에 대해 알고 있습니다. 대안이 있습니다.

  4. 포조에는 논리가 없습니다. 수업을 직접 작성하는 경우 누군가는 자신에게 편리한 메서드를 추가하고 싶은 유혹을 느낄 수 있습니다. 이 메서드는 생성된 클래스뿐만 아니라 json 스키마에도 추가할 수 없습니다.

아마 그게 전부일 것입니다.

결론:

나는 json 방식이 프로젝트 간 상호작용을 위한 매우 좋은 형식이라는 것을 전달하려고 노력했습니다. 어느 날 프로젝트에서 그를 만났고 그는 내 마음에 빠졌습니다. 나는 거의 모든 곳에서 그것들을 사용합니다. 예, 소스를 보려면 프로젝트를 조합해야 하기 때문에 이것이 항상 편리한 것은 아닙니다. 하지만 이것은 포조(pojo)입니다. 즉, 거기에는 논리가 있을 수 없고 회로에도 아무 것도 없을 것임을 의미합니다. PS.. 가끔 설명이 부족해서 좋은 보고서가 포함된 동영상이 있습니다. Kirill Merkushev - 자동화 문제를 해결하는 방법으로서의 코드 생성.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION