Java Language
JSON i Java
Sök…
Introduktion
JSON (JavaScript Object Notation) är ett lätt, textbaserat, språkoberoende datautbytesformat som är lätt för människor och maskiner att läsa och skriva. JSON kan representera två strukturerade typer: objekt och matriser. JSON används ofta i Ajax-applikationer, konfigurationer, databaser och RESTful webbtjänster. Java API för JSON Processing tillhandahåller bärbara API: er för att analysera, generera, transformera och fråga JSON.
Anmärkningar
Detta exempel fokuserar på att analysera och skapa JSON i Java med hjälp av olika bibliotek som Google Gson- biblioteket, Jackson Object Mapper och andra ..
Exempel på andra bibliotek kan hittas här: Hur man analyserar JSON i Java
Kodningsdata som JSON
Om du behöver skapa ett JSONObject
och lägga in data i det, överväg följande exempel:
// 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"]
}
*/
Avkodning av JSON-data
Om du behöver hämta data från ett JSONObject
överväger du följande exempel:
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 metoder
JSONObject
och JSONArray
har några metoder som är mycket användbara när du hanterar en möjlighet att ett värde du försöker få inte finns eller är av en annan typ.
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"
Samma regler gäller för getXXX
/ optXXX
metoderna i JSONArray
.
Objekt mot JSON (Gson Library)
Låt oss anta att du har en klass som heter Person
med bara name
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Koda:
Gson g = new Gson();
Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}
Naturligtvis måste Gson- burken vara på klassvägen.
JSON To Object (Gson Library)
Låt oss anta att du har en klass som heter Person
med bara name
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Koda:
Gson gson = new Gson();
String json = "{\"name\": \"John\"}";
Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John
Du måste ha gson-bibliotek på din klassväg.
Extrahera enstaka element från 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
Använda Jackson Object Mapper
Pojo-modell
public class Model {
private String firstName;
private String lastName;
private int age;
/* Getters and setters not shown for brevity */
}
Exempel: String to Object
Model outputObject = objectMapper.readValue(
"{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
Model.class);
System.out.println(outputObject.getFirstName());
//result: John
Exempel: Objekt mot sträng
String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}
detaljer
Importmeddelande behövs:
import com.fasterxml.jackson.databind.ObjectMapper;
Mavenberoende: jackson-databind
ObjectMapper
instans
//creating one
ObjectMapper objectMapper = new ObjectMapper();
-
ObjectMapper
är trådhäftigt - rekommenderas: ha en delad statisk instans
deserialiseringsundantag:
<T> T readValue(String content, Class<T> valueType)
-
valueType
måste anges - returen kommer att vara av denna typ - Utlöser
-
IOException
- vid I / O-problem på låg nivå -
JsonParseException
- om underliggande input innehåller ogiltigt innehåll -
JsonMappingException
- om ingången JSON-strukturen inte stämmer överens med objektstruktur
-
Exempel på användning (jsonString är inmatningssträngen):
Model fromJson = objectMapper.readValue(jsonString, Model.class);
Metod för serialisering:
String writeValueAsString (Objektvärde)
- Utlöser
-
JsonProcessingException
vid fel - Obs! Innan version 2.1 ingår IOException, kastaklausul; 2.1 tog bort den.
-
JSON Iteration
Iterera över JSONObject
egenskaper
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
}
Iterera över JSONArray
värden
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 - kedjemetoder
Du kan använda metodkedjning när du arbetar med JSONObject
och JSONArray
.
JSONObjekteksempel
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
Om du behöver lägga till en egenskap med ett null
bör du använda den fördefinierade statiska slutliga JSONObject.NULL
och inte standard Java null
.
JSONObject.NULL
är ett sentinelvärde som används för att uttryckligen definiera en egenskap med ett tomt värde.
JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL); //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null
Notera
JSONObject.NULL.equals(null); //returns true
Vilket är en tydlig överträdelse av Java.equals()
kontrakt:
För alla referensvärden som inte är null, ska x.equals (null) returnera falskt
JsonArray to Java List (Gson Library)
Här är en enkel JsonArray som du vill konvertera till en Java ArrayList
:
{
"list": [
"Test_String_1",
"Test_String_2"
]
}
JsonArray
nu JsonArray
'listan' till följande metod som returnerar en motsvarande Java ArrayList
:
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;
}
Du bör lägga till följande mavenberoende till din POM.xml
fil:
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
Eller så borde du ha burken com.google.code.gson:gson:jar:<version>
på din klassväg.
Deserialisera JSON-samling till samling av objekt med hjälp av Jackson
Anta att du har en Pojo klass Person
public class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Och du vill analysera det i en JSON-grupp eller en karta över Personobjekt. På grund av typ radering kan du inte konstruera klasser av List<Person>
och Map<String, Person>
vid körning direkt (och därmed använda dem för att deserialisera JSON) . För att övervinna denna begränsning tillhandahåller TypeFactory
två tillvägagångssätt - TypeFactory
och TypeReference
.
TypeFactory
Den här metoden är att använda en fabrik (och dess statiska verktygsfunktion) för att bygga din typ åt dig. Parametrarna det tar är den samling du vill använda (lista, ställa in etc.) och klassen du vill lagra i den samlingen.
TypeReference
Typreferensmetoden verkar enklare eftersom den sparar lite att skriva och ser renare ut. TypeReference accepterar en typparameter, där du passerar önskad typlista List<Person>
. Du anmäler helt enkelt detta TypeReference-objekt och använder det som din typbehållare.
Låt oss nu titta på hur du faktiskt deserialiserar din JSON till ett Java-objekt. Om din JSON är formaterad som en matris kan du deserialisera den som en lista. Om det finns en mer komplex kapslad struktur, vill du deserialisera till en karta. Vi kommer att titta på exempel på båda.
Deserializing JSON array
String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"
TypeFactory-strategi
CollectionType listType =
factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);
TypeReference-strategi
TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);
Deserializing JSON-karta
String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"
TypeFactory-strategi
CollectionType mapType =
factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);
TypeReference-strategi
TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);
detaljer
Importering används:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
Användade instanser:
ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();
Notera
Medan TypeReference
metoden kan se bättre ut har den flera nackdelar:
-
TypeReference
bör instanseras med anonym klass - Du bör ge generisk explicitet
Underlåtenhet att göra det kan leda till förlust av argument av generisk typ vilket kommer att leda till deserialiseringsfel.