Jackson JSON Java Parser ist sehr beliebt und wird auch im Spring-Framework verwendet. Java JSON Processing API ist nicht sehr benutzerfreundlich und bietet keine Funktionen für die automatische Umwandlung von Json in Java-Objekte und umgekehrt. Glücklicherweise haben wir einige alternative APIs, die wir für die JSON-Verarbeitung verwenden können. Im letzten Artikel haben wir über Google Gson API gelernt und gesehen, wie einfach es zu verwenden ist.
Jackson JSON Java Parser
Um die Jackson JSON Java API in unserem Projekt zu verwenden, können wir sie dem Projekt-Build-Pfad hinzufügen oder, wenn Sie Maven verwenden, können wir untenstehende Abhängigkeit hinzufügen.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
Das Jar-Datei von jackson-databind hängt von den Bibliotheken jackson-core und jackson-annotations ab. Wenn Sie sie direkt zum Build-Pfad hinzufügen, stellen Sie sicher, dass Sie alle drei hinzufügen, sonst erhalten Sie Laufzeitfehler. Die Jackson JSON Parser-API bietet eine einfache Möglichkeit, JSON in ein POJO-Objekt umzuwandeln, und unterstützt eine einfache Konvertierung von JSON-Daten in eine Map. Jackson unterstützt auch Generika und wandelt sie direkt von JSON in ein Objekt um.
Beispiel für Jackson JSON
Für unser Beispiel zur Konvertierung von JSON in POJO-/Java-Objekte nehmen wir ein komplexes Beispiel mit verschachtelten Objekten und Arrays. Wir verwenden Arrays, Listen und Maps in Java-Objekten für die Konvertierung. Unser komplexes JSON ist in einer Datei „employee.txt“ mit folgender Struktur gespeichert:
{
"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"
}
}
Wir haben folgende Java-Klassen, die den JSON-Daten entsprechen.
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();
}
}
Die Klasse „Address“ entspricht dem inneren Objekt in den Wurzel-JSON-Daten.
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“ ist das Java-Bean, das das Wurzel-JSON-Objekt darstellt. Sehen wir uns nun an, wie wir JSON in Java-Objekte mithilfe der Jackson JSON-Parser-API umwandeln können.
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 {
// JSON-Dateidaten in einen String einlesen
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
// ObjectMapper-Instanz erstellen
ObjectMapper objectMapper = new ObjectMapper();
// JSON-String in ein Objekt umwandeln
Employee emp = objectMapper.readValue(jsonData, Employee.class);
System.out.println("Employee Object\n"+emp);
// Objekt in JSON-String umwandeln
Employee emp1 = createEmployee();
// ObjectMapper für die Ausgabeformatierung konfigurieren
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// Ausgabe auf die Konsole schreiben, kann in beliebigen Ausgabestream wie Datei geschrieben werden
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;
}
}
Wenn wir das obige Programm ausführen, erhalten Sie folgende Ausgabe.
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
json gleich wie oben drucken
com.fasterxml.jackson.databind.ObjectMapper ist die wichtigste Klasse in der Jackson-API, die die Methoden readValue() und writeValue() bereitstellt, um JSON in ein Java-Objekt und ein Java-Objekt in JSON zu transformieren. Die Klasse ObjectMapper kann wiederverwendet werden, und wir können sie einmal als Singleton-Objekt initialisieren. Es gibt so viele überladene Versionen der Methoden readValue() und writeValue(), um mit Byte-Arrays, Dateien, Ein- / Ausgabe-Streams und Reader / Writer-Objekten zu arbeiten.
Jackson JSON – Konvertierung von JSON in eine Map
Manchmal haben wir ein JSON-Objekt wie unten in der Datei data.txt:
{
"name": "David",
"role": "Manager",
"city": "Los Angeles"
}
und wir möchten es in eine Map konvertieren und nicht in ein Java-Objekt mit denselben Eigenschaften und Schlüsseln. Das können wir sehr einfach mit zwei Methoden im Jackson JSON API mit folgendem Code tun:
// JSON in Map konvertieren
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);
// eine andere Möglichkeit
myMap = objectMapper.readValue(mapData, new TypeReference>() {});
System.out.println("Map using TypeReference: "+myMap);
Nach Ausführung des obigen Snippets erhalten wir folgende Ausgabe:
Map is: {name=David, role=Manager, city=Los Angeles}
Map using TypeReference: {name=David, role=Manager, city=Los Angeles}
Jackson JSON – Lesen eines bestimmten JSON-Schlüssels
Manchmal haben wir JSON-Daten und sind nur an einigen Werten der Schlüssel interessiert, daher ist es keine gute Idee, das gesamte JSON in ein Objekt umzuwandeln. Die Jackson JSON API bietet die Möglichkeit, JSON-Daten als Baum, ähnlich dem DOM-Parser, zu lesen, und wir können bestimmte Elemente des JSON-Objekts über diesen Zugriff. Der folgende Codeausschnitt zeigt, wie man bestimmte Einträge aus einer JSON-Datei liest.
// JSON-Datei in String einlesen
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
// ObjectMapper-Instanz erstellen
ObjectMapper objectMapper = new ObjectMapper();
// JSON wie DOM-Parser lesen
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());
}
Bei Ausführung des obigen Codeausschnitts erhalten wir folgende Ausgabe:
id = 123
Phone No = 123456
Phone No = 987654
Jackson JSON – JSON-Dokument bearbeiten
Die Jackson JSON Java API bietet nützliche Methoden zum Hinzufügen, Bearbeiten und Entfernen von Schlüsseln aus JSON-Daten, die dann als neue JSON-Datei gespeichert oder in einen Stream geschrieben werden können. Der folgende Code zeigt uns, wie dies einfach gemacht werden kann.
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
ObjectMapper objectMapper = new ObjectMapper();
// JsonNode erstellen
JsonNode rootNode = objectMapper.readTree(jsonData);
// JSON-Daten aktualisieren
((ObjectNode) rootNode).put("id", 500);
// neuen Schlüsselwert hinzufügen
((ObjectNode) rootNode).put("test", "test value");
// vorhandenen Schlüssel entfernen
((ObjectNode) rootNode).remove("role");
((ObjectNode) rootNode).remove("properties");
objectMapper.writeValue(new File("updated_emp.txt"), rootNode);
Wenn Sie den obigen Code ausführen und nach der neuen Datei suchen, werden Sie feststellen, dass sie die Schlüssel „role“ und „properties“ nicht enthält. Sie werden auch feststellen, dass der Wert von „id“ auf 500 aktualisiert wurde und ein neuer Schlüssel „test“ zur Datei „updated_emp.txt“ hinzugefügt wurde.
Jackson JSON Streaming API Beispiel
Jackson JSON Java API bietet auch Unterstützung für Streaming, was bei der Arbeit mit großen JSON-Daten hilfreich ist, da es die gesamte Datei als Token liest und weniger Speicher verwendet. Das einzige Problem bei der Streaming-API ist, dass wir uns um alle Tokens kümmern müssen, während wir die JSON-Daten analysieren. Wenn wir JSON-Daten wie {“role”:“Manager”} haben, erhalten wir folgende Tokens in der Reihenfolge – { (Startobjekt), “role” (Schlüsselname), “Manager” (Schlüsselwert) und } (Endobjekt). Doppelpunkt (:) ist das Trennzeichen in JSON und wird daher nicht als Token betrachtet.
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 {
// JsonParser-Objekt erstellen
JsonParser jsonParser = new JsonFactory().createParser(new File("employee.txt"));
// Schleife durch die Tokens
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();
// Mitarbeiterobjekt ausgeben
System.out.println("Employee Object\n\n"+emp);
}
private static void parseJSON(JsonParser jsonParser, Employee emp,
List phoneNums, boolean insidePropertiesObj) throws JsonParseException, IOException {
// Schleife durch die JsonTokens
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();
// Verschachteltes Objekt, rekursiver Aufruf
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 ist die Jackson JSON-Streaming-API zum Lesen von JSON-Daten, wir verwenden sie, um Daten aus der Datei zu lesen, und dann wird die parseJSON()-Methode verwendet, um durch die Tokens zu iterieren und sie zu verarbeiten, um unser Java-Objekt zu erstellen. Beachten Sie, dass die Methode parseJSON() rekursiv für „address“ aufgerufen wird, da es sich um ein verschachteltes Objekt in den JSON-Daten handelt. Zum Analysieren von Arrays durchlaufen wir das JSON-Dokument. Wir können die Klasse JsonGenerator verwenden, um JSON-Daten mit der Streaming-API zu generieren.
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"));
// für schönes Drucken
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 ist im Vergleich zu JsonParser einfach zu verwenden. Das ist alles für das schnelle Nachschlagetutorial zum Jackson JSON Parser Java API. Die Jackson JSON Java API ist einfach zu verwenden und bietet viele Optionen für die Benutzerfreundlichkeit von Entwicklern, die mit JSON-Daten arbeiten. Laden Sie das Projekt über den untenstehenden Link herunter und probieren Sie es aus, um mehr Optionen zur Jackson Json API zu erkunden.
Laden Sie das Jackson JSON-Projekt herunter
Referenz: Jackson GitHub-Seite
Source:
https://www.digitalocean.com/community/tutorials/jackson-json-java-parser-api-example-tutorial