JavaRush /Java Blog /Random-ID /Skema JSON: mengapa dan siapa yang membutuhkannya

Skema JSON: mengapa dan siapa yang membutuhkannya

Dipublikasikan di grup Random-ID
Halo, pengembara. Hari ini saya ingin bercerita tentang sedikit keajaiban. Anda mungkin pernah mendengar tentang json. Ini adalah bahasa universal: dapat dipahami oleh mesin dan mudah dibaca oleh manusia. Berikut adalah contoh khas pesan json:
{
   "помещение":{
      "название":"избушка",
      "разумна":true
   },
   "основание":{
      "тип":"курьи ноги",
      "количество":2
   },
   "проживающие":[
      {
         "Name":"Баба Яга",
         "профиль":"ведьма"
      }
   ],
   "местоположение":{
      "address":"граница леса"
   }
}
Nyaman untuk berkomunikasi seperti itu, bukan? Jika Anda tidak tahu apa itu json sebelumnya, sekarang Anda tahu. Bagaimana cara menggunakan ini dalam kode Java? JSON telah menjadi format universal. Itu singkatan dari JavaScript Object Notation, tetapi telah lama melampaui javascript dan digunakan hampir di mana-mana. Java memiliki beberapa perpustakaan yang membuat bekerja dengan json lebih mudah. Inilah yang paling terkenal: Saya akan menggunakan yang kedua. Ada 2 versinya : codehaus dan fastxml , saya tidak melihat adanya perbedaan di dalamnya, jadi Anda dapat menggunakan salah satu di sini. Berikut ini sepotong kode:
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue("сюда json", "сюда класс");
akan membantu menerjemahkan json menjadi suatu objek. Dan kita sedang mendekati hal yang paling penting. Menulis kelas untuk json ini. Anda dapat melakukannya secara manual, buat struktur seperti ini:
-----------------------------------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;

}
Saya secara khusus menghilangkan getter, setter, konstruktor, dan atribut pojo lainnya, jika tidak, Anda akan bosan membuang-buang =) Sekarang lihat di sini:
{
  "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
}
Ini adalah diagram json dari struktur di atas. Sekarang saatnya menjelaskan mengapa Anda membutuhkannya. Ini akan menghilangkan kebutuhan untuk menulis kelas dan memeliharanya. Ada proyek yang bagus jsonschema2pojo . Ia menawarkan plugin untuk pembuat proyek (Maven, Gradle) yang akan menulis kelas-kelas ini untuk Anda pada waktu pembuatan. Berikut ini contoh dari proyek saya:
<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>
Ini adalah pengaturannya. Yang paling menarik ada di sini:
<useCommonsLang3>true</useCommonsLang3>
<includeConstructors>true</includeConstructors>
<generateBuilders>true</generateBuilders>
<includeToString>true</includeToString>
<usePrimitives>true</usePrimitives>
Ini adalah instruksi tentang cara menulis kelas: useCommonsLang3 - gunakan perpustakaan CommonsLang3 includeConstructors - akan menulis konstruktor generateBuilders - akan membuat pembuat pola includeToString - tambahkan toString usePrimitives - instruksi untuk menggunakan primitif Bagaimana ini lebih baik daripada kode yang ditulis sendiri ?
  1. Anda dapat menyesuaikan kelas dengan satu baris. Misalnya, Anda perlu menambahkan akhiran Pojo ke setiap kelas. Cukup tambahkan <classNameSuffix>Pojo</classNameSuffix> untuk merakit proyek - dan selesai. Jika tidak, kita harus mengubah nama setiap kelas secara manual.

    Ada banyak parameter ini, ada baiknya membaca semuanya di dokumen

  2. Jika proyek Anda memiliki konsumen, akan lebih mudah untuk memberikan skema json daripada kelas Java. Seperti yang sudah saya katakan, skema ini bersifat universal dan konsumen cukup membuat pojo dalam bahasanya sendiri.

  3. Ukurannya jauh lebih kecil. Contoh di atas banyak memuat informasi yang tidak selalu diperlukan, misalnya pola dan contoh. Tetapi jika Anda mengembalikannya ke kode java, itu juga akan bertambah banyak. Dan jangan lupa tentang kode template, yang ditunjukkan dalam diagram oleh beberapa pengaturan di plugin, tetapi Anda harus menulisnya sendiri di kode tersebut. Dan ya, saya tahu tentang Lombok, ada alternatif lain.

  4. Tidak ada logika di pojo. Ketika kelas Anda ditulis sendiri, seseorang mungkin tergoda untuk menambahkan metode yang nyaman bagi mereka. Metode ini tidak dapat ditambahkan ke skema json, serta ke kelas yang dihasilkan.

Mungkin itu saja.

Kesimpulan:

Saya mencoba menyampaikan bahwa skema json adalah format yang sangat baik untuk interaksi antar proyek. Suatu hari saya bertemu dengannya di sebuah proyek, dan dia jatuh ke dalam hati saya. Saya menggunakannya hampir di mana saja. Ya, ini tidak selalu nyaman, karena untuk melihat sumbernya, Anda perlu menyusun proyek. Tapi ini pojo, artinya tidak mungkin ada logika di sana, dan tidak akan ada sirkuit. PS.. terkadang saya menjelaskan dengan buruk, jadi inilah video dengan laporan yang bagus: Kirill Merkushev - Pembuatan kode sebagai cara untuk memecahkan masalah otomatisasi.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION