Java Language
JSON in Java
Ricerca…
introduzione
JSON (JavaScript Object Notation) è un formato di scambio di dati leggero, basato su testo e indipendente dalla lingua, che è facile da leggere e scrivere per gli utenti e le macchine. JSON può rappresentare due tipi strutturati: oggetti e matrici. JSON viene spesso utilizzato nelle applicazioni Ajax, nelle configurazioni, nei database e nei servizi Web RESTful. L'API Java per JSON Processing fornisce API portatili per analizzare, generare, trasformare e interrogare JSON.
Osservazioni
Questo esempio si concentra sull'analisi e sulla creazione di JSON in Java utilizzando varie librerie come la libreria Google Gson , il Jackson Object Mapper e altri ..
Gli esempi che utilizzano altre librerie possono essere trovati qui: Come analizzare JSON in Java
Codifica dei dati come JSON
Se è necessario creare un oggetto JSONObject
e inserire dati, considerare il seguente esempio:
// 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"]
}
*/
Decodifica dei dati JSON
Se è necessario ottenere dati da un oggetto JSONObject
, considerare il seguente esempio:
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 metodi
JSONObject
e JSONArray
hanno alcuni metodi che sono molto utili mentre si tratta di una possibilità che un valore che stai cercando di ottenere non esiste o è di un altro tipo.
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"
Le stesse regole si applicano ai metodi getXXX
/ optXXX
di JSONArray
.
Object To JSON (Gson Library)
Supponiamo che tu abbia una classe chiamata Person
con un solo name
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Codice:
Gson g = new Gson();
Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}
Ovviamente il vaso Gson deve trovarsi sul classpath.
JSON To Object (Gson Library)
Supponiamo che tu abbia una classe chiamata Person
con un solo name
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Codice:
Gson gson = new Gson();
String json = "{\"name\": \"John\"}";
Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John
Devi avere la libreria gson nel tuo classpath.
Estrai singolo elemento da 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
Utilizzando Jackson Object Mapper
Modello di Pojo
public class Model {
private String firstName;
private String lastName;
private int age;
/* Getters and setters not shown for brevity */
}
Esempio: stringa su oggetto
Model outputObject = objectMapper.readValue(
"{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
Model.class);
System.out.println(outputObject.getFirstName());
//result: John
Esempio: oggetto da stringa
String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}
Dettagli
Importazione necessaria:
import com.fasterxml.jackson.databind.ObjectMapper;
Dipendenza da Maven: jackson-databind
ObjectMapper
//creating one
ObjectMapper objectMapper = new ObjectMapper();
-
ObjectMapper
è thread-safe - consigliato: avere un'istanza statica condivisa
deserializzazione:
<T> T readValue(String content, Class<T> valueType)
-
valueType
deve essere specificato - il ritorno sarà di questo tipo - Genera
-
IOException
: in caso di problemi I / O di basso livello -
JsonParseException
- se l'input sottostante contiene contenuti non validi -
JsonMappingException
- se la struttura JSON di input non corrisponde alla struttura dell'oggetto
-
Esempio di utilizzo (jsonString è la stringa di input):
Model fromJson = objectMapper.readValue(jsonString, Model.class);
Metodo per la serializzazione:
String writeValueAsString (Valore oggetto)
- Genera
-
JsonProcessingException
in caso di errore - Nota: prima della versione 2.1, la clausola throws includeva IOException; 2.1 rimosso.
-
JSON Iteration
JSONObject
su proprietà JSONObject
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
su valori di 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: metodi di concatenamento
È possibile utilizzare il metodo di concatenamento mentre si lavora con JSONObject
e JSONArray
.
Esempio di JSONObject
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
Se è necessario aggiungere una proprietà con un valore null
, è necessario utilizzare il JSONObject.NULL
finale statico predefinito e non il riferimento null
standard di Java.
JSONObject.NULL
è un valore sentinella utilizzato per definire esplicitamente una proprietà con un valore vuoto.
JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL); //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null
Nota
JSONObject.NULL.equals(null); //returns true
Che è una chiara violazione del contratto Java.equals()
:
Per qualsiasi valore di riferimento non nullo x, x.equals (null) deve restituire false
Elenco da JsonArray a Java (Gson Library)
Ecco un semplice JsonArray che vorresti convertire in una ArrayList
Java:
{
"list": [
"Test_String_1",
"Test_String_2"
]
}
Ora passa l''elenco' di JsonArray
al seguente metodo che restituisce una corrispondente ArrayList
Java:
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;
}
È necessario aggiungere la seguente dipendenza POM.xml
file 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>
O dovresti avere il jar com.google.code.gson:gson:jar:<version>
nel classpath.
Deserializzare la raccolta JSON nella collezione di oggetti usando Jackson
Supponi di avere una Person
classe pojo
public class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
E tu vuoi analizzarlo in un array JSON o in una mappa di oggetti Person. A causa della cancellazione dei tipi non è possibile costruire classi di List<Person>
e Map<String, Person>
direttamente in runtime (e quindi usarle per deserializzare JSON) . Per superare questa limitazione, Jackson offre due approcci: TypeFactory
e TypeReference
.
TypeFactory
L'approccio qui utilizzato è quello di utilizzare una fabbrica (e la sua funzione di utilità statica) per creare il tuo tipo per te. I parametri necessari sono la raccolta che si desidera utilizzare (elenco, set, ecc.) E la classe che si desidera archiviare in quella raccolta.
TypeReference
L'approccio al tipo di riferimento sembra più semplice perché consente di risparmiare un po 'di digitazione e sembra più pulito. TypeReference accetta un parametro type, in cui si passa il tipo di List<Person>
desiderato List<Person>
. Basta istanziare questo oggetto TypeReference e usarlo come contenitore del tipo.
Ora vediamo come deserializzare realmente il tuo JSON in un oggetto Java. Se il tuo JSON è formattato come array, puoi deserializzare come elenco. Se esiste una struttura nidificata più complessa, è necessario deserializzare su una mappa. Vedremo esempi di entrambi.
Deserializzazione dell'array JSON
String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"
Approccio TypeFactory
CollectionType listType =
factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);
Tipo Approccio di riferimento
TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);
Deserializzazione della mappa JSON
String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"
Approccio TypeFactory
CollectionType mapType =
factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);
Tipo Approccio di riferimento
TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);
Dettagli
Importazione utilizzata:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
Istanze utilizzate:
ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();
Nota
Mentre TypeReference
approccio TypeReference
può sembrare migliore ha diversi inconvenienti:
-
TypeReference
dovrebbe essere istanziato usando una classe anonima - Dovresti fornire generica esplicita
Non riuscendo a farlo potrebbe portare alla perdita dell'argomento di tipo generico che porterà a un errore di deserializzazione.