Le parseur Jackson JSON Java est très populaire et utilisé dans le framework Spring également. L’API de traitement JSON en Java n’est pas très conviviale et ne fournit pas de fonctionnalités pour la transformation automatique de Json en objet Java et vice versa. Heureusement, nous avons quelques API alternatives que nous pouvons utiliser pour le traitement JSON. Dans le dernier article, nous avons appris à propos de l’API Google Gson et avons vu à quel point il est facile à utiliser.
Le parseur Jackson JSON Java
Pour utiliser l’API Jackson JSON Java dans notre projet, nous pouvons l’ajouter au chemin de construction du projet ou, si vous utilisez Maven, nous pouvons ajouter la dépendance ci-dessous.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
jackson-databind jar dépend de jackson-core et des bibliothèques jackson-annotations, donc si vous les ajoutez directement au chemin de construction, assurez-vous d’ajouter les trois, sinon vous obtiendrez une erreur d’exécution. L’API de l’analyseur JSON de Jackson fournit un moyen facile de convertir JSON en objet POJO et prend en charge une conversion facile en Map à partir des données JSON. Jackson prend également en charge les génériques et les convertit directement de JSON en objet.
Exemple JSON de Jackson
Pour notre exemple de conversion JSON en objet POJO/Java, nous prendrons un exemple complexe avec un objet et des tableaux imbriqués. Nous utiliserons des tableaux, des listes et des Maps dans les objets Java pour la conversion. Notre JSON complexe est stocké dans un fichier employee.txt avec la structure suivante:
{
"id": 123,
"name": "Pankaj",
"permanent": true,
"address": {
"street": "Albany Dr",
"city": "San Jose",
"zipcode": 95129
},
"phoneNumbers": [
123456,
987654
],
"role": "Manager",
"cities": [
"Los Angeles",
"New York"
],
"properties": {
"age": "29 years",
"salary": "1000 USD"
}
}
Nous avons les classes Java suivantes correspondant aux données JSON.
package com.journaldev.jackson.model;
public class Address {
private String street;
private String city;
private int zipcode;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getZipcode() {
return zipcode;
}
public void setZipcode(int zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString(){
return getStreet() + ", "+getCity()+", "+getZipcode();
}
}
La classe Address correspond à l’objet interne dans les données JSON racine.
package com.journaldev.jackson.model;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Employee {
private int id;
private String name;
private boolean permanent;
private Address address;
private long[] phoneNumbers;
private String role;
private List<String> cities;
private Map<String, String> properties;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isPermanent() {
return permanent;
}
public void setPermanent(boolean permanent) {
this.permanent = permanent;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public long[] getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(long[] phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("***** Employee Details *****\n");
sb.append("ID="+getId()+"\n");
sb.append("Name="+getName()+"\n");
sb.append("Permanent="+isPermanent()+"\n");
sb.append("Role="+getRole()+"\n");
sb.append("Phone Numbers="+Arrays.toString(getPhoneNumbers())+"\n");
sb.append("Address="+getAddress()+"\n");
sb.append("Cities="+Arrays.toString(getCities().toArray())+"\n");
sb.append("Properties="+getProperties()+"\n");
sb.append("*****************************");
return sb.toString();
}
public List<String> getCities() {
return cities;
}
public void setCities(List<String> cities) {
this.cities = cities;
}
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}
Employee est la classe Java représentant l’objet JSON racine. Voyons maintenant comment nous pouvons transformer JSON en objet Java en utilisant l’API d’analyseur JSON de Jackson.
package com.journaldev.jackson.json;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.journaldev.jackson.model.Address;
import com.journaldev.jackson.model.Employee;
public class JacksonObjectMapperExample {
public static void main(String[] args) throws IOException {
// lire les données du fichier JSON en tant que chaîne
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
// créer une instance ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// convertir la chaîne JSON en objet
Employee emp = objectMapper.readValue(jsonData, Employee.class);
System.out.println("Employee Object\n"+emp);
// convertir l'objet en chaîne JSON
Employee emp1 = createEmployee();
// configurer ObjectMapper pour une sortie bien formatée
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// écriture dans la console, peut écrire dans n'importe quel flux de sortie tel qu'un fichier
StringWriter stringEmp = new StringWriter();
objectMapper.writeValue(stringEmp, emp1);
System.out.println("Employee JSON is\n"+stringEmp);
}
public static Employee createEmployee() {
Employee emp = new Employee();
emp.setId(100);
emp.setName("David");
emp.setPermanent(false);
emp.setPhoneNumbers(new long[] { 123456, 987654 });
emp.setRole("Manager");
Address add = new Address();
add.setCity("Bangalore");
add.setStreet("BTM 1st Stage");
add.setZipcode(560100);
emp.setAddress(add);
List cities = new ArrayList();
cities.add("Los Angeles");
cities.add("New York");
emp.setCities(cities);
Map props = new HashMap();
props.put("salary", "1000 Rs");
props.put("age", "28 years");
emp.setProperties(props);
return emp;
}
}
Lorsque vous exécutez le programme ci-dessus, vous obtiendrez la sortie suivante.
Employee Object
***** Employee Details *****
ID=123
Name=Pankaj
Permanent=true
Role=Manager
Phone Numbers=[123456, 987654]
Address=Albany Dr, San Jose, 95129
Cities=[Los Angeles, New York]
Properties={age=29 years, salary=1000 USD}
*****************************
Employee JSON is
// Impression du même contenu que le fichier JSON ci-dessus
com.fasterxml.jackson.databind.ObjectMapper est la classe la plus importante dans l’API Jackson qui fournit les méthodes readValue() et writeValue() pour transformer JSON en objet Java et objet Java en JSON. La classe ObjectMapper peut être réutilisée, et nous pouvons l’initialiser une fois en tant qu’objet Singleton. Il existe de nombreuses versions surchargées des méthodes readValue() et writeValue() pour travailler avec un tableau d’octets, un fichier, des flux d’entrée/sortie et des objets Reader/Writer.
Jackson JSON – Conversion JSON en Map
Parfois, nous avons un objet JSON comme ci-dessous, dans le fichier data.txt :
{
"name": "David",
"role": "Manager",
"city": "Los Angeles"
}
et nous voulons le convertir en une Map et non en un objet Java avec les mêmes propriétés et clés. Nous pouvons le faire très facilement avec l’API Jackson JSON en utilisant deux méthodes avec le code ci-dessous :
// Conversion du JSON en Map
byte[] mapData = Files.readAllBytes(Paths.get("data.txt"));
Map myMap = new HashMap();
ObjectMapper objectMapper = new ObjectMapper();
myMap = objectMapper.readValue(mapData, HashMap.class);
System.out.println("Map is: "+myMap);
// Une autre façon
myMap = objectMapper.readValue(mapData, new TypeReference>() {});
System.out.println("Map using TypeReference: "+myMap);
Une fois que nous exécutons le snippet ci-dessus, nous obtenons la sortie suivante :
Map is: {name=David, role=Manager, city=Los Angeles}
Map using TypeReference: {name=David, role=Manager, city=Los Angeles}
Jackson JSON – Lire une clé JSON spécifique
Parfois, nous avons des données JSON et nous sommes intéressés par seulement quelques-unes des valeurs des clés, donc dans ce cas, convertir tout le JSON en objet n’est pas une bonne idée. L’API Jackson JSON offre la possibilité de lire les données JSON comme un arbre semblable à un analyseur DOM et nous pouvons ainsi lire des éléments spécifiques de l’objet JSON. Le code ci-dessous fournit un extrait pour lire des entrées spécifiques d’un fichier JSON.
// lire les données du fichier JSON en chaîne
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
// créer une instance ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// lire JSON comme un analyseur DOM
JsonNode rootNode = objectMapper.readTree(jsonData);
JsonNode idNode = rootNode.path("id");
System.out.println("id = "+idNode.asInt());
JsonNode phoneNosNode = rootNode.path("phoneNumbers");
Iterator elements = phoneNosNode.elements();
while(elements.hasNext()){
JsonNode phone = elements.next();
System.out.println("Phone No = "+phone.asLong());
}
Nous obtenons la sortie suivante lorsque nous exécutons le code ci-dessus.
id = 123
Phone No = 123456
Phone No = 987654
Jackson JSON – Modifier le document JSON
L’API Java Jackson JSON fournit des méthodes utiles pour ajouter, éditer et supprimer des clés des données JSON, puis nous pouvons les enregistrer en tant que nouveau fichier JSON ou les écrire dans n’importe quel flux. Le code ci-dessous nous montre comment faire cela facilement.
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
ObjectMapper objectMapper = new ObjectMapper();
// créer JsonNode
JsonNode rootNode = objectMapper.readTree(jsonData);
// mettre à jour les données JSON
((ObjectNode) rootNode).put("id", 500);
// ajouter une nouvelle paire clé-valeur
((ObjectNode) rootNode).put("test", "test value");
// supprimer une clé existante
((ObjectNode) rootNode).remove("role");
((ObjectNode) rootNode).remove("properties");
objectMapper.writeValue(new File("updated_emp.txt"), rootNode);
Si vous exécutez le code ci-dessus et recherchez le nouveau fichier, vous remarquerez qu’il ne contient pas les clés « role » et « properties ». Vous remarquerez également que la valeur « id » est mise à jour à 500 et une nouvelle clé « test » est ajoutée au fichier updated_emp.txt.
Exemple de l’API de diffusion Jackson JSON
L’API Jackson JSON Java offre également une prise en charge de la diffusion qui est utile pour travailler avec de grandes données JSON car elle lit l’intégralité du fichier sous forme de jetons et utilise moins de mémoire. Le seul problème avec l’API de diffusion est que nous devons prendre soin de tous les jetons lors de l’analyse des données JSON. Si nous avons des données JSON comme {« role »: « Manager »}, nous obtiendrons les jetons suivants dans l’ordre – { (démarrer l’objet), « role » (nom de la clé), « Manager » (valeur de la clé) et } (fin de l’objet). Le deux-points (:) est le délimiteur en JSON et n’est donc pas considéré comme un jeton.
package com.journaldev.jackson.json;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.journaldev.jackson.model.Address;
import com.journaldev.jackson.model.Employee;
public class JacksonStreamingReadExample {
public static void main(String[] args) throws JsonParseException, IOException {
//créer l'objet JsonParser
JsonParser jsonParser = new JsonFactory().createParser(new File("employee.txt"));
//parcourir les jetons
Employee emp = new Employee();
Address address = new Address();
emp.setAddress(address);
emp.setCities(new ArrayList());
emp.setProperties(new HashMap());
List phoneNums = new ArrayList();
boolean insidePropertiesObj=false;
parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
long[] nums = new long[phoneNums.size()];
int index = 0;
for(Long l :phoneNums){
nums[index++] = l;
}
emp.setPhoneNumbers(nums);
jsonParser.close();
//imprimer l'objet employé
System.out.println("Employee Object\n\n"+emp);
}
private static void parseJSON(JsonParser jsonParser, Employee emp,
List phoneNums, boolean insidePropertiesObj) throws JsonParseException, IOException {
//parcourir les jetons Json
while(jsonParser.nextToken() != JsonToken.END_OBJECT){
String name = jsonParser.getCurrentName();
if("id".equals(name)){
jsonParser.nextToken();
emp.setId(jsonParser.getIntValue());
}else if("name".equals(name)){
jsonParser.nextToken();
emp.setName(jsonParser.getText());
}else if("permanent".equals(name)){
jsonParser.nextToken();
emp.setPermanent(jsonParser.getBooleanValue());
}else if("address".equals(name)){
jsonParser.nextToken();
//objet imbriqué, appel récursif
parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
}else if("street".equals(name)){
jsonParser.nextToken();
emp.getAddress().setStreet(jsonParser.getText());
}else if("city".equals(name)){
jsonParser.nextToken();
emp.getAddress().setCity(jsonParser.getText());
}else if("zipcode".equals(name)){
jsonParser.nextToken();
emp.getAddress().setZipcode(jsonParser.getIntValue());
}else if("phoneNumbers".equals(name)){
jsonParser.nextToken();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
phoneNums.add(jsonParser.getLongValue());
}
}else if("role".equals(name)){
jsonParser.nextToken();
emp.setRole(jsonParser.getText());
}else if("cities".equals(name)){
jsonParser.nextToken();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
emp.getCities().add(jsonParser.getText());
}
}else if("properties".equals(name)){
jsonParser.nextToken();
while(jsonParser.nextToken() != JsonToken.END_OBJECT){
String key = jsonParser.getCurrentName();
jsonParser.nextToken();
String value = jsonParser.getText();
emp.getProperties().put(key, value);
}
}
}
}
}
JsonParser est l’API de diffusion JSON de Jackson pour lire les données JSON, nous l’utilisons pour lire les données du fichier, puis la méthode parseJSON() est utilisée pour parcourir les jetons et les traiter afin de créer notre objet Java. Remarquez que la méthode parseJSON() est appelée récursivement pour « address » car c’est un objet imbriqué dans les données JSON. Pour analyser les tableaux, nous parcourons le document JSON. Nous pouvons utiliser la classe JsonGenerator pour générer des données JSON avec l’API de diffusion.
package com.journaldev.jackson.json;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Set;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.journaldev.jackson.model.Employee;
public class JacksonStreamingWriteExample {
public static void main(String[] args) throws IOException {
Employee emp = JacksonObjectMapperExample.createEmployee();
JsonGenerator jsonGenerator = new JsonFactory()
.createGenerator(new FileOutputStream("stream_emp.txt"));
//pour une impression agréable
jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
jsonGenerator.writeStartObject(); // start root object
jsonGenerator.writeNumberField("id", emp.getId());
jsonGenerator.writeStringField("name", emp.getName());
jsonGenerator.writeBooleanField("permanent", emp.isPermanent());
jsonGenerator.writeObjectFieldStart("address"); //start address object
jsonGenerator.writeStringField("street", emp.getAddress().getStreet());
jsonGenerator.writeStringField("city", emp.getAddress().getCity());
jsonGenerator.writeNumberField("zipcode", emp.getAddress().getZipcode());
jsonGenerator.writeEndObject(); //end address object
jsonGenerator.writeArrayFieldStart("phoneNumbers");
for(long num : emp.getPhoneNumbers())
jsonGenerator.writeNumber(num);
jsonGenerator.writeEndArray();
jsonGenerator.writeStringField("role", emp.getRole());
jsonGenerator.writeArrayFieldStart("cities"); //start cities array
for(String city : emp.getCities())
jsonGenerator.writeString(city);
jsonGenerator.writeEndArray(); //closing cities array
jsonGenerator.writeObjectFieldStart("properties");
Set keySet = emp.getProperties().keySet();
for(String key : keySet){
String value = emp.getProperties().get(key);
jsonGenerator.writeStringField(key, value);
}
jsonGenerator.writeEndObject(); //closing properties
jsonGenerator.writeEndObject(); //closing root object
jsonGenerator.flush();
jsonGenerator.close();
}
}
JsonGenerator est facile à utiliser par rapport à JsonParser. C’est tout pour le tutoriel de référence rapide sur l’API Java Jackson JSON Parser. L’API Java Jackson JSON est facile à utiliser et offre de nombreuses options pour faciliter le travail des développeurs avec les données JSON. Téléchargez le projet à partir du lien ci-dessous et explorez-le pour découvrir plus d’options sur l’API Jackson Json.
Télécharger le projet Jackson JSON
Référence : Page GitHub de Jackson
Source:
https://www.digitalocean.com/community/tutorials/jackson-json-java-parser-api-example-tutorial