Szukaj…


Wprowadzenie

JSON (JavaScript Object Notation) to lekki, tekstowy, niezależny od języka format wymiany danych, który jest łatwy do odczytania i zapisu przez ludzi i maszyny. JSON może reprezentować dwa typy strukturalne: obiekty i tablice. JSON jest często używany w aplikacjach, konfiguracjach, bazach danych i usługach sieciowych RESTful Ajax. Interfejs API Java dla JSON Processing zapewnia przenośne interfejsy API do analizowania, generowania, przekształcania i odpytywania JSON.

Uwagi

Ten przykład koncentruje się na analizie i tworzeniu JSON w Javie przy użyciu różnych bibliotek, takich jak biblioteka Google Gson , Jackson Object Mapper i inne ..

Przykłady korzystania z innych bibliotek można znaleźć tutaj: Jak analizować JSON w Javie

Kodowanie danych jako JSON

Jeśli chcesz utworzyć obiekt JSONObject i umieścić w nim dane, rozważ następujący przykład:

// 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"]
   }
*/

Dekodowanie danych JSON

Jeśli potrzebujesz uzyskać dane z obiektu JSONObject , rozważ następujący przykład:

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);

metody optXXX a metody getXXX

JSONObject i JSONArray mają kilka metod, które są bardzo przydatne podczas radzenia sobie z możliwością, że wartość, którą próbujesz uzyskać, nie istnieje lub jest innego typu.

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"

Te same zasady stosuje się do getXXX / optXXX metod JSONArray .

Object To JSON (Gson Library)

Załóżmy, że masz klasę o nazwie Person z tylko name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Kod:

Gson g = new Gson();

Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}

Oczywiście słoik Gson musi znajdować się na ścieżce klas.

JSON To Object (Gson Library)

Załóżmy, że masz klasę o nazwie Person z tylko name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Kod:

Gson gson = new Gson();
String json = "{\"name\": \"John\"}";

Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John

Musisz mieć bibliotekę gson w swojej ścieżce klasy.

Wyodrębnij pojedynczy element z 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

Korzystanie z Jackson Object Mapper

Pojo Model

public class Model {
    private String firstName;
    private String lastName;
    private int age;
    /* Getters and setters not shown for brevity */        
}

Przykład: ciąg do obiektu

Model outputObject = objectMapper.readValue(
     "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
     Model.class);
System.out.println(outputObject.getFirstName());
//result: John

Przykład: Object to String

String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}

Detale

Wymagane oświadczenie importu:

import com.fasterxml.jackson.databind.ObjectMapper;

Zależność Maven: jackson-databind

Instancja ObjectMapper

//creating one
ObjectMapper objectMapper = new ObjectMapper();
  • ObjectMapper jest wątkowo bezpieczny
  • zalecane: mieć wspólną, statyczną instancję

Deserializacja:

<T> T readValue(String content, Class<T> valueType)  
  • valueType musi być określony - zwracany będzie ten typ
  • Rzuty
    • IOException - w przypadku problemu niskiego poziomu we / wy
    • JsonParseException - jeśli podstawowe dane wejściowe zawierają niepoprawną treść
    • JsonMappingException - jeśli wejściowa struktura JSON nie pasuje do struktury obiektu

Przykład użycia (jsonString jest łańcuchem wejściowym):

Model fromJson = objectMapper.readValue(jsonString, Model.class);

Metoda serializacji:

String writeValueAsString (wartość obiektu)

  • Rzuty
    • JsonProcessingException w przypadku błędu
    • Uwaga: przed wersją 2.1 klauzula rzucania zawierała wyjątek IOException; 2.1 usunął go.

Iteracja JSON

JSONObject właściwościach 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 wartościach 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 - metody łączenia

Podczas pracy z JSONObject i JSONArray można używać łączenia łańcuchowego JSONArray .

Przykład 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

Aby dodać właściwość o wartości null , należy użyć wstępnie zdefiniowanego statycznego końcowego JSONObject.NULL a nie standardowego odwołania Java o null .

JSONObject.NULL jest wartością wartownika używaną do jawnego zdefiniowania właściwości o pustej wartości.

JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL);   //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null

Uwaga

JSONObject.NULL.equals(null); //returns true

Co jest wyraźnym naruszeniem umowy Java.equals() :

Dla każdej wartości odniesienia innej niż null x, x.equals (null) powinno zwracać wartość false

JsonArray to Java List (Gson Library)

Oto prosty JsonArray, który chciałbyś przekonwertować na Java ArrayList :

{
    "list": [
                "Test_String_1",
                "Test_String_2"
            ] 
}

Teraz JsonArray „listę” JsonArray do następującej metody, która zwraca odpowiednią listę 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;
}

Do pliku POM.xml należy dodać następującą zależność maven:

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>

Lub powinieneś mieć słoik com.google.code.gson:gson:jar:<version> w ścieżce klasy.

Deserializuj kolekcję JSON do kolekcji obiektów za pomocą Jacksona

Załóżmy, że masz klasę pojo Person

public class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

I chcesz parsować go do tablicy JSON lub mapy obiektów Person. Z powodu usunięcia typu nie można bezpośrednio tworzyć klas List<Person> i Map<String, Person> w środowisku wykonawczym (a tym samym używać ich do deserializacji JSON) . Aby pokonać to ograniczenie, Jackson oferuje dwa podejścia - TypeFactory i TypeReference .

TypeFactory

Podejście tutaj polega na użyciu fabryki (i jej statycznej funkcji użyteczności), aby zbudować swój typ dla ciebie. Wymagane parametry to kolekcja, której chcesz użyć (lista, zestaw itp.) Oraz klasa, którą chcesz przechowywać w tej kolekcji.

TypeReference

Podejście do typowania wydaje się prostsze, ponieważ pozwala zaoszczędzić trochę pisania i wygląda na czystsze. TypeReference akceptuje parametr typu, w którym przekazujesz pożądany typ List<Person> . Wystarczy utworzyć instancję tego obiektu TypeReference i użyć go jako kontenera typu.

Teraz przyjrzyjmy się, jak dokonać deserializacji JSON w obiekt Java. Jeśli Twój JSON jest sformatowany jako tablica, możesz dokonać deserializacji jako List. Jeśli istnieje bardziej złożona struktura zagnieżdżona, należy dokonać deserializacji na mapę. Przyjrzymy się przykładom obu.

Deserializowanie tablicy JSON

String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"

Podejście TypeFactory

CollectionType listType = 
    factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);

Podejście TypeReference

TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);

Deserializowanie mapy JSON

String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"

Podejście TypeFactory

CollectionType mapType = 
    factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);

Podejście TypeReference

TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);

Detale

Zastosowana instrukcja importu:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

Użyte wystąpienia:

ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();

Uwaga

Chociaż podejście TypeReference może wyglądać lepiej, ma kilka wad:

  1. TypeReference należy utworzyć za pomocą klasy anonimowej
  2. Powinieneś zapewnić ogólne wyjaśnienie

Niezastosowanie się do tego może prowadzić do utraty argumentu typu ogólnego, co doprowadzi do niepowodzenia deserializacji.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow