Java Language
JSON in Java
Zoeken…
Invoering
JSON (JavaScript Object Notation) is een lichtgewicht, op tekst gebaseerd, taalonafhankelijk formaat voor gegevensuitwisseling dat voor mensen en machines gemakkelijk te lezen en te schrijven is. JSON kan twee gestructureerde typen vertegenwoordigen: objecten en arrays. JSON wordt vaak gebruikt in Ajax-toepassingen, configuraties, databases en RESTful-webservices. De Java API voor JSON-verwerking biedt draagbare API's om JSON te parseren, genereren, transformeren en opvragen.
Opmerkingen
Dit voorbeeld richt zich op het parseren en maken van JSON in Java met behulp van verschillende bibliotheken zoals de Google Gson- bibliotheek, Jackson Object Mapper en andere ..
Voorbeelden met andere bibliotheken zijn hier te vinden: Hoe JSON in Java te parseren
Gegevens coderen als JSON
Als u een JSONObject
moet maken en gegevens erin moet plaatsen, overweeg dan het volgende voorbeeld:
// 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-gegevens decoderen
Als u gegevens van een JSONObject
, overweeg dan het volgende voorbeeld:
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 versus getXXX-methoden
JSONObject
en JSONArray
hebben een paar methoden die erg handig zijn bij het omgaan met een mogelijkheid dat een waarde die u probeert te krijgen niet bestaat of van een ander type is.
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"
Dezelfde regels zijn van toepassing op de getXXX
/ optXXX
methoden van JSONArray
.
Object To JSON (Gson Library)
Laten we aannemen dat je een klasse hebt met de naam Person
met alleen de 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"}
Natuurlijk moet de Gson- pot zich op het klassenpad bevinden.
JSON naar object (Gson-bibliotheek)
Laten we aannemen dat je een klasse hebt met de naam Person
met alleen de 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
Je moet een Gson-bibliotheek in je klassenpad hebben.
Pak een enkel element uit JSON
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 gebruiken
Pojo-model
public class Model {
private String firstName;
private String lastName;
private int age;
/* Getters and setters not shown for brevity */
}
Voorbeeld: tekenreeks naar object
Model outputObject = objectMapper.readValue(
"{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
Model.class);
System.out.println(outputObject.getFirstName());
//result: John
Voorbeeld: object naar string
String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}
Details
Importverklaring vereist:
import com.fasterxml.jackson.databind.ObjectMapper;
Maven-afhankelijkheid: jackson-databind
ObjectMapper
instantie
//creating one
ObjectMapper objectMapper = new ObjectMapper();
-
ObjectMapper
is threadsafe - aanbevolen: gebruik een gedeelde, statische instantie
deserialisatie:
<T> T readValue(String content, Class<T> valueType)
-
valueType
moet worden opgegeven - het rendement is van dit type - Werpt
-
IOException
- in geval van een I / O-probleem van laag niveau -
JsonParseException
- als onderliggende invoer ongeldige inhoud bevat -
JsonMappingException
- als de ingevoerde JSON-structuur niet overeenkomt met de objectstructuur
-
Gebruiksvoorbeeld (jsonString is de invoertekenreeks):
Model fromJson = objectMapper.readValue(jsonString, Model.class);
Methode voor serialisatie:
String writeValueAsString (objectwaarde)
- Werpt
-
JsonProcessingException
in geval van een fout - Opmerking: vóór versie 2.1 bevat de worpclausule IOException; 2.1 verwijderd.
-
JSON Iteratie
Herhaal de JSONObject
eigenschappen
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
}
JSONArray
waarden van JSONArray
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 - kettingmethoden
U kunt method chaining gebruiken terwijl u met JSONObject
en JSONArray
.
JSONObject voorbeeld
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
Als u een woning met een toe te voegen null
waarde, moet u de vooraf gedefinieerde static final gebruiken JSONObject.NULL
en niet de standaard Java null
referentie.
JSONObject.NULL
is een schildwachtwaarde die wordt gebruikt om een eigenschap met een lege waarde expliciet te definiëren.
JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL); //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null
Notitie
JSONObject.NULL.equals(null); //returns true
Dat is een duidelijke schending van het Java.equals()
-contract:
Voor elke niet-nul referentiewaarde x moet x.equals (null) false retourneren
JsonArray to Java List (Gson Library)
Hier is een eenvoudige JsonArray die u wilt converteren naar een Java ArrayList
:
{
"list": [
"Test_String_1",
"Test_String_2"
]
}
Geef de 'lijst' van JsonArray
nu door aan de volgende methode die een overeenkomstige Java ArrayList
retourneert:
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;
}
U moet de volgende maven-afhankelijkheid toevoegen aan uw POM.xml
bestand:
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
Of u moet de jar com.google.code.gson:gson:jar:<version>
in uw classpath hebben.
Deserialiseer JSON-verzameling naar verzameling objecten met Jackson
Stel dat je een Person
pojo-klasse hebt
public class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
En u wilt het parseren in een JSON-array of een kaart met Person-objecten. Vanwege het wissen van het type kunt u tijdens runtime geen klassen van List<Person>
en Map<String, Person>
(en deze dus gebruiken om JSON te deserialiseren) . Om deze beperking te overwinnen biedt jackson twee benaderingen - TypeFactory
en TypeReference
.
TypeFactory
De aanpak hier is om een fabriek (en de statische hulpprogramma-functie) te gebruiken om uw type voor u te bouwen. De parameters die daarvoor nodig zijn, zijn de verzameling die u wilt gebruiken (lijst, set, enz.) En de klasse die u in die verzameling wilt opslaan.
TypeReference
De typebenadering lijkt eenvoudiger omdat het u een beetje typeert en er schoner uitziet. TypeReference accepteert een parameter type, waarbij u het gewenste typelijst List<Person>
doorgeeft. U maakt eenvoudigweg dit TypeReference-object en gebruikt het als uw typecontainer.
Laten we nu eens kijken hoe u uw JSON daadwerkelijk kunt deserialiseren in een Java-object. Als uw JSON is opgemaakt als een array, kunt u deze deserialiseren als een lijst. Als er een complexere geneste structuur is, wilt u de-deserialiseren naar een kaart. We zullen naar voorbeelden van beide kijken.
JSON-array deserialiseren
String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"
TypeFactory-benadering
CollectionType listType =
factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);
TypeReference benadering
TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);
JSON-kaart deserialiseren
String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"
TypeFactory-benadering
CollectionType mapType =
factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);
TypeReference benadering
TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);
Details
Gebruikte importverklaring:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
Instanties gebruikt:
ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();
Notitie
Hoewel de TypeReference
aanpak er misschien beter uitziet, heeft dit verschillende nadelen:
-
TypeReference
moet worden geïnstantieerd met behulp van anonieme klasse - U moet generieke duidelijkheid bieden
Als u dit niet doet, kan het argument van het generieke type verloren gaan, wat kan leiden tot mislukking van de deserialisatie.