Suche…


Einführung

JSON (JavaScript Object Notation) ist ein leichtes, textbasiertes, sprachunabhängiges Datenaustauschformat, das von Menschen und Maschinen leicht gelesen und geschrieben werden kann. JSON kann zwei strukturierte Typen darstellen: Objekte und Arrays. JSON wird häufig in Ajax-Anwendungen, -Konfigurationen, Datenbanken und RESTful-Webdiensten verwendet. Die Java-API für die JSON-Verarbeitung bietet portable APIs zum Analysieren, Generieren, Transformieren und Abfragen von JSON.

Bemerkungen

Dieses Beispiel konzentriert sich auf das Analysieren und Erstellen von JSON in Java mithilfe verschiedener Bibliotheken wie der Google Gson- Bibliothek, Jackson Object Mapper und anderen.

Beispiele für andere Bibliotheken finden Sie hier: So analysieren Sie JSON in Java

Daten als JSON kodieren

Wenn Sie ein JSONObject erstellen und Daten darin JSONObject , betrachten Sie das folgende Beispiel:

// Create a new javax.json.JSONObject instance.
JSONObject first = new JSONObject();

first.put("foo", "bar");
first.put("temperature", 21.5);
first.put("year", 2016);

// Add a second object.
JSONObject second = new JSONObject();
second.put("Hello", "world");
first.put("message", second);

// Create a new JSONArray with some values
JSONArray someMonths = new JSONArray(new String[] { "January", "February" });
someMonths.put("March");
// Add another month as the fifth element, leaving the 4th element unset.
someMonths.put(4, "May");

// Add the array to our object
object.put("months", someMonths);

// Encode
String json = object.toString();

// An exercise for the reader: Add pretty-printing!
/* {
       "foo":"bar",
       "temperature":21.5,
       "year":2016,
       "message":{"Hello":"world"},
       "months":["January","February","March",null,"May"]
   }
*/

JSON-Daten dekodieren

Wenn Sie Daten von einem JSONObject , beachten Sie das folgende Beispiel:

String json = "{\"foo\":\"bar\",\"temperature\":21.5,\"year\":2016,\"message\":{\"Hello\":\"world\"},\"months\":[\"January\",\"February\",\"March\",null,\"May\"]}";

// Decode the JSON-encoded string
JSONObject object = new JSONObject(json);

// Retrieve some values
String foo = object.getString("foo");
double temperature = object.getDouble("temperature");
int year = object.getInt("year");

// Retrieve another object
JSONObject secondary = object.getJSONObject("message");
String world = secondary.getString("Hello");

// Retrieve an array
JSONArray someMonths = object.getJSONArray("months");
// Get some values from the array
int nMonths = someMonths.length();
String february = someMonths.getString(1);

optXXX vs getXXX-Methoden

JSONObject und JSONArray verfügen über einige Methoden, die sehr nützlich sind, wenn es um die Möglichkeit geht, dass ein Wert, den Sie erhalten JSONArray , nicht existiert oder von einem anderen Typ ist.

JSONObject obj = new JSONObject();
obj.putString("foo", "bar");

// For existing properties of the correct type, there is no difference
obj.getString("foo");        // returns "bar"
obj.optString("foo");        // returns "bar"
obj.optString("foo", "tux"); // returns "bar"

// However, if a value cannot be coerced to the required type, the behavior differs
obj.getInt("foo");      // throws JSONException
obj.optInt("foo");      // returns 0
obj.optInt("foo", 123); // returns 123

// Same if a property does not exist
obj.getString("undefined");        // throws JSONException
obj.optString("undefined");        // returns ""
obj.optString("undefined", "tux"); // returns "tux"

Die gleichen Regeln gelten für die getXXX / optXXX Methoden von JSONArray .

Objekt für JSON (Gson Library)

Nehmen wir an, Sie haben eine Klasse namens Person mit nur name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Code:

Gson g = new Gson();

Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}

Natürlich muss sich das Gson- Glas auf dem Klassenpfad befinden.

JSON in Objekt (Gson-Bibliothek)

Nehmen wir an, Sie haben eine Klasse namens Person mit nur name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Code:

Gson gson = new Gson();
String json = "{\"name\": \"John\"}";

Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John

Sie müssen eine Gson-Bibliothek in Ihrem Klassenpfad haben.

Einzelne Elemente aus JSON extrahieren

String json = "{\"name\": \"John\", \"age\":21}";

JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John
System.out.println(jsonObject.get("age").getAsInt()); //21

Jackson Object Mapper verwenden

Pojo-Modell

public class Model {
    private String firstName;
    private String lastName;
    private int age;
    /* Getters and setters not shown for brevity */        
}

Beispiel: String to Object

Model outputObject = objectMapper.readValue(
     "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
     Model.class);
System.out.println(outputObject.getFirstName());
//result: John

Beispiel: Object to String

String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}

Einzelheiten

Importanweisung erforderlich:

import com.fasterxml.jackson.databind.ObjectMapper;

Maven-Abhängigkeit: Jackson-Datenbind

ObjectMapper Instanz

//creating one
ObjectMapper objectMapper = new ObjectMapper();
  • ObjectMapper ist THREAD
  • empfohlen: eine gemeinsam genutzte statische Instanz haben

Deserialisierung:

<T> T readValue(String content, Class<T> valueType)  
  • valueType muss angegeben werden - die Rückgabe wird von diesem Typ sein
  • Wirft
    • IOException - bei einem E / A-Problem auf niedriger Ebene
    • JsonParseException - Wenn die zugrunde liegende Eingabe ungültigen Inhalt enthält
    • JsonMappingException - wenn die Eingabe-JSON-Struktur nicht mit der Objektstruktur übereinstimmt

Verwendungsbeispiel (jsonString ist die Eingabezeichenfolge):

Model fromJson = objectMapper.readValue(jsonString, Model.class);

Methode zur Serialisierung:

String writeValueAsString (Objektwert)

  • Wirft
    • JsonProcessingException im Fehlerfall
    • Anmerkung: Vor Version 2.1 enthielt die Throws-Klausel IOException. 2.1 entfernt.

JSON-Iteration

Durchlaufen Sie die JSONObject Eigenschaften

JSONObject obj = new JSONObject("{\"isMarried\":\"true\", \"name\":\"Nikita\", \"age\":\"30\"}");
Iterator<String> keys = obj.keys();//all keys: isMarried, name & age
while (keys.hasNext()) {                      //as long as there is another key
      String key = keys.next();               //get next key 
      Object value = obj.get(key);            //get next value by key
      System.out.println(key + " : " + value);//print key : value
}

Durchlaufen Sie die JSONArray Werte

JSONArray arr = new JSONArray();        //Initialize an empty array
//push (append) some values in:
arr.put("Stack");
arr.put("Over");
arr.put("Flow");
for (int i = 0; i < arr.length(); i++) {//iterate over all values
    Object value = arr.get(i);          //get value
    System.out.println(value);          //print each value
}

JSON Builder - Verkettungsmethoden

Sie können die Methodenverkettung verwenden, während Sie mit JSONObject und JSONArray .

JSONObject-Beispiel

JSONObject obj = new JSONObject();//Initialize an empty JSON object 
//Before: {}
obj.put("name","Nikita").put("age","30").put("isMarried","true");
//After: {"name":"Nikita","age":30,"isMarried":true}

JSONArray

JSONArray arr = new JSONArray();//Initialize an empty array
//Before: []
arr.put("Stack").put("Over").put("Flow");
//After: ["Stack","Over","Flow"]

JSONObject.NULL

Wenn Sie eine Immobilie mit einem hinzufügen müssen null Wert, sollten Sie die vordefinierten statische Endverwendung JSONObject.NULL und nicht die Standard - Java null Referenz.

JSONObject.NULL ist ein Sentinel-Wert, mit dem eine Eigenschaft explizit mit einem leeren Wert definiert wird.

JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL);   //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null

Hinweis

JSONObject.NULL.equals(null); //returns true

Welches ist eine klare Verletzung des Java.equals() Vertrags:

Für jeden Referenzwert x, der nicht Null ist, sollte x.equals (null) den Wert false zurückgeben

JsonArray zu Java-Liste (Gson-Bibliothek)

Hier ist ein einfacher JsonArray, den Sie in eine Java ArrayList konvertieren möchten:

{
    "list": [
                "Test_String_1",
                "Test_String_2"
            ] 
}

JsonArray nun die JsonArray -Liste an die folgende Methode, die eine entsprechende Java- ArrayList zurückgibt:

public ArrayList<String> getListString(String jsonList){
    Type listType = new TypeToken<List<String>>() {}.getType();
    //make sure the name 'list' matches the name of 'JsonArray' in your 'Json'.
    ArrayList<String> list = new Gson().fromJson(jsonList, listType);    
    return list;
}

Sie sollten Ihrer POM.xml Datei die folgende Maven-Abhängigkeit POM.xml :

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>

Oder Sie sollten den jar com.google.code.gson:gson:jar:<version> in Ihrem Klassenpfad haben.

Deserialisieren Sie die JSON-Sammlung in eine Sammlung von Objekten mit Jackson

Angenommen, Sie haben eine Pojo-Klasse Person

public class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Und Sie möchten es in ein JSON-Array oder eine Karte von Personenobjekten analysieren. Aufgrund der Typenlöschung können Sie zur Laufzeit keine Klassen aus List<Person> und Map<String, Person> direkt erstellen (und daher zur Deserialisierung von JSON verwenden) . Um diese Einschränkung zu überwinden, bietet jackson zwei Ansätze an - TypeFactory und TypeReference .

TypeFactory

Der hier verfolgte Ansatz besteht darin, eine Factory (und ihre statische Dienstprogrammfunktion) zu verwenden, um Ihren Typ für Sie zu erstellen. Die dafür benötigten Parameter sind die Sammlung, die Sie verwenden möchten (Liste, Satz usw.), und die Klasse, die Sie in dieser Sammlung speichern möchten.

TypReferenz

Der Typ-Referenz-Ansatz scheint einfacher zu sein, da er Ihnen weniger Schreibarbeit erspart und sauberer aussieht. TypeReference akzeptiert einen Typparameter, bei dem Sie den gewünschten Typ List<Person> . Sie instanziieren dieses TypeReference-Objekt einfach und verwenden es als Typcontainer.

Sehen wir uns nun an, wie Sie Ihr JSON tatsächlich in ein Java-Objekt deserialisieren. Wenn Ihr JSON als Array formatiert ist, können Sie es als Liste deserialisieren. Wenn eine komplexere verschachtelte Struktur vorhanden ist, müssen Sie eine Deserialisierung für eine Map durchführen. Wir werden uns Beispiele für beide ansehen.

Deserialisierung des JSON-Arrays

String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"

TypeFactory-Ansatz

CollectionType listType = 
    factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);

TypeReference-Ansatz

TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);

Deserialisierung der JSON-Karte

String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"

TypeFactory-Ansatz

CollectionType mapType = 
    factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);

TypeReference-Ansatz

TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);

Einzelheiten

Import-Anweisung verwendet:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

Verwendete Instanzen:

ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();

Hinweis

Während der TypeReference Ansatz möglicherweise besser aussieht, hat er mehrere Nachteile:

  1. TypeReference sollte mithilfe einer anonymen Klasse instanziiert werden
  2. Sie sollten generische Erklärung geben

Andernfalls kann das generische Argument verloren gehen, was zu einem Deserialisierungsfehler führen kann.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow