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:

  1. TypeReference moet worden geïnstantieerd met behulp van anonieme klasse
  2. 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.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow