JavaRush /Blog Java /Random-FR /Schéma Json : pourquoi et qui en a besoin

Schéma Json : pourquoi et qui en a besoin

Publié dans le groupe Random-FR
Bonjour, vagabond. Aujourd'hui, je veux vous parler d'un peu de magie. Vous avez probablement déjà entendu parler de json. C’est un langage tellement universel : il est compris par les machines et facilement lu par les humains. Voici un exemple typique de message json :
{
   "помещение":{
      "название":"избушка",
      "разумна":true
   },
   "основание":{
      "тип":"курьи ноги",
      "количество":2
   },
   "проживающие":[
      {
         "Name":"Баба Яга",
         "профиль":"ведьма"
      }
   ],
   "местоположение":{
      "address":"граница леса"
   }
}
C’est pratique de communiquer comme ça, n’est-ce pas ? Si vous ne saviez pas ce qu'était json auparavant, vous le savez maintenant. Comment utiliser cela dans du code Java ? Json est devenu un format universel. Il signifie JavaScript Object Notation, mais il dépasse depuis longtemps le javascript et est utilisé presque partout. Java dispose de plusieurs bibliothèques qui facilitent le travail avec json. Voici les plus célèbres : J'utiliserai le deuxième. Il en existe 2 versions : codehaus et fastxml , je n'ai remarqué aucune différence entre elles, vous pouvez donc en utiliser n'importe laquelle ici. Voici un morceau de code :
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue("сюда json", "сюда класс");
aidera à traduire json en un objet. Et nous approchons du plus important. Écrire une classe pour ce json. Vous pouvez le faire manuellement, créer une structure ressemblant à ceci :
-----------------------------------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;

}
J'ai spécifiquement omis les getters, setters, constructeurs et autres attributs pojo, sinon vous en auriez marre de gaspiller =) Maintenant, regardez ici :
{
  "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
}
Il s'agit du diagramme json de la structure ci-dessus. Il est maintenant temps d'expliquer pourquoi vous en avez besoin. Cela éliminera le besoin d’écrire des cours et de les maintenir. Il existe un si bon projet jsonschema2pojo . Il propose des plugins pour les constructeurs de projets (Maven, Gradle) qui écriront ces classes pour vous au moment de la construction. Voici un exemple de mon projet :
<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>
C'est son décor. Le plus intéressant est ici :
<useCommonsLang3>true</useCommonsLang3>
<includeConstructors>true</includeConstructors>
<generateBuilders>true</generateBuilders>
<includeToString>true</includeToString>
<usePrimitives>true</usePrimitives>
Ceci est une instruction sur la façon d'écrire une classe : useCommonsLang3 - utilise la bibliothèque CommonsLang3 includeConstructors - écrira un constructeur generateBuilders - construira un générateur de modèles includeToString - ajoute toString usePrimitives - une instruction pour utiliser des primitives En quoi est-ce meilleur que le code écrit à la maison ?
  1. Vous pouvez personnaliser les classes avec une seule ligne. Par exemple, vous devez ajouter le suffixe Pojo à chaque classe. Ajoutez simplement <classNameSuffix>Pojo</classNameSuffix> pour assembler le projet - et vous avez terminé. Sinon, nous devrions changer les noms de chaque classe manuellement.

    Il y a beaucoup de ces paramètres, cela vaut la peine de les lire tous dans la documentation

  2. Si votre projet a un consommateur, il sera beaucoup plus facile de lui donner des schémas json plutôt que des classes java. Comme je l'ai déjà dit, les systèmes sont universels et le consommateur va simplement générer du pojo dans sa propre langue.

  3. Ils sont beaucoup plus petits. L'exemple ci-dessus contient de nombreuses informations qui ne sont pas toujours nécessaires, par exemple des modèles et des exemples. Mais si vous les renvoyez au code Java, celui-ci augmentera également beaucoup. Et n'oubliez pas le code du modèle, qui est indiqué dans les diagrammes par quelques paramètres du plugin, mais vous devez l'écrire vous-même dans le code. Et oui, je connais Lombok, il existe une alternative.

  4. Aucune logique dans pojo. Lorsque vos cours sont auto-écrits, quelqu’un peut être tenté d’ajouter une méthode qui lui convient. La méthode ne peut pas être ajoutée au schéma json, ni à la classe générée.

C'est probablement tout.

Conclusion:

J'ai essayé de faire comprendre que les schémas JSON sont un très bon format pour l'interaction entre les projets. Un jour, je l'ai rencontré sur un projet et il est tombé dans mon cœur. Je les utilise presque partout. Oui, ce n'est pas toujours pratique, car pour visualiser les sources, vous devez assembler le projet. Mais c’est un pojo, ce qui signifie qu’il ne peut y avoir de logique là-bas, et qu’il n’y en aura pas avec les circuits. PS.. parfois j'explique mal, alors voici une vidéo avec un bon rapport : Kirill Merkushev - La génération de code comme moyen de résoudre les problèmes d'automatisation.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION