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:

  1. TypeReference bör instanseras med anonym klass
  2. 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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow