Java Language
JSON in Java
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:
-
TypeReference
sollte mithilfe einer anonymen Klasse instanziiert werden - Sie sollten generische Erklärung geben
Andernfalls kann das generische Argument verloren gehen, was zu einem Deserialisierungsfehler führen kann.