JavaRush /Java блогу /Random-KY /Json схемасы: эмне үчүн жана кимге керек

Json схемасы: эмне үчүн жана кимге керек

Группада жарыяланган
Саламатсызбы, саякатчы. Бүгүн мен силерге бир аз сыйкыр жөнүндө айткым келет. Сиз json жөнүндө уккандырсыз. Бул ушунчалык универсалдуу тил: аны машиналар түшүнөт жана адамдар оңой окушат. Бул жерде json билдирүүнүн типтүү мисалы:
{
   "помещение":{
      "название":"избушка",
      "разумна":true
   },
   "основание":{
      "тип":"курьи ноги",
      "количество":2
   },
   "проживающие":[
      {
         "Name":"Баба Яга",
         "профиль":"ведьма"
      }
   ],
   "местоположение":{
      "address":"граница леса"
   }
}
Ушундай баарлашуу ыңгайлуу, туурабы? Мурда json эмне экенин билбесеңиз, азыр билесиз. Муну java codeунда кантип колдонсо болот? Json универсалдуу формат болуп калды. Бул JavaScript Object Notation дегенди билдирет, бирок көптөн бери JavaScript чегинен чыгып кеткен жана дээрлик бардык жерде колдонулат. Javaда json менен иштөөнү жеңилдеткен бир нече китепкана бар. Бул жерде абдан белгилүү болуп саналат: Мен экинчисин колдоном. Алардын 2 versionсы бар : codehaus жана fasterxml , мен алардан эч кандай айырмачылыктарды байкаган жокмун, андыктан каалаганын бул жерден колдонсоңуз болот. Бул жерде codeдун бир бөлүгү:
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue("сюда json", "сюда класс");
jsonды an objectке которууга жардам берет. Ал эми биз эң негизги нерсеге жакындап жатабыз. Бул 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;

}
Мен атайын алуучуларды, орнотуучуларды, конструкторлорду жана башка 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 - конструкторду жазат Builders - үлгү куруучуну курат includeToString - toString кошуу usePrimitives - примитивдерди колдонуу боюнча нускама Бул үйдө жазылган codeдон эмнеси менен жакшыраак? ?
  1. Сиз класстарды бир сызык менен ыңгайлаштыра аласыз. Мисалы, ар бир класска Pojo суффикс кошуу керек. Проектти чогултуу үчүн жөн гана <classNameSuffix>Pojo</classNameSuffix> кошуңуз - жана бүттүңүз. Болбосо ар бир класстын атын кол менен өзгөртүүгө туура келет.

    Бул параметрлер көп, алардын бардыгы жөнүндө documentтерден окуп чыгуу керек

  2. Эгерде сиздин долбоорңузда керектөөчү болсо, ага java класстарына караганда json схемаларын берүү оңой болот. Мен буга чейин айткандай, схемалар универсалдуу жана керектөөчү жөн гана өз тorнде пожо жаратат.

  3. Алар алда канча кичине. Жогорудагы мисалда дайыма эле зарыл боло бербеген көптөгөн маалыматтар камтылган, мисалы, үлгүлөр жана мисалдар. Бирок аларды Java codeуна кайтарсаңыз, ал дагы көп өсөт. Плагинде бир нече орнотуулар менен диаграммаларда көрсөтүлгөн шаблон codeу жөнүндө унутпаңыз, бирок сиз аны codeго өзүңүз жазышыңыз керек. Ооба, мен Ломбок жөнүндө билем, альтернатива бар.

  4. Поджодо логика жок. Сиздин класстар өз алдынча жазылган болгондо, кимдир бирөө алар үчүн ыңгайлуу болгон ыкманы кошууга азгырылышы мүмкүн. Методду json схемасына, ошондой эле түзүлгөн класска кошууга болбойт.

Ушунун баары ушул болсо керек.

Жыйынтык:

Мен json схемалары долбоорлордун ортосундагы өз ара аракеттенүү үчүн абдан жакшы формат экенин билдирүүгө аракет кылдым. Күндөрдүн биринде мен аны менен бир долбоордо таанышып калдым, ал менин жүрөгүмө кирип кетти. Мен аларды дээрлик бардык жерде колдоном. Ооба, бул дайыма эле ыңгайлуу эмес, анткени булактарды көрүү үчүн сиз долбоорду чогултушуңуз керек. Бирок бул пожо, демек, ал жерде логика болушу мүмкүн эмес жана схемалар болбойт. PS.. Кээде мен начар түшүндүрүп берем, ошондуктан бул жерде жакшы баяндамасы бар видео: Кирилл Меркушев - Кодду түзүү автоматташтыруу көйгөйлөрүн чечүү жолу катары.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION