Поиск…


Вступление

JSON (JavaScript Object Notation) представляет собой легкий, текстовый, независимый от языка формат обмена данными, который легко людям и машинам читать и писать. JSON может представлять два структурированных типа: объекты и массивы. JSON часто используется в приложениях Ajax, конфигурациях, базах данных и веб-службах RESTful. Java API для JSON Processing предоставляет портативные API для анализа, генерации, преобразования и запроса JSON.

замечания

В этом примере основное внимание уделяется разбору и созданию JSON в Java с использованием различных библиотек, таких как библиотека Google Gson , Jackson Object Mapper и другие.

Примеры использования других библиотек можно найти здесь: Как разбирать JSON в Java

Кодирование данных как JSON

Если вам нужно создать JSONObject и поместить в него данные, рассмотрите следующий пример:

// 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

Если вам нужно получить данные из JSONObject , рассмотрите следующий пример:

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

JSONObject и JSONArray есть несколько методов, которые очень полезны при работе с возможностью того, что значение, которое вы пытаетесь получить, не существует или имеет другой тип.

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"

Те же правила применяются к getXXX / optXXX JSONArray .

Объект для JSON (библиотека Gson)

Допустим, у вас есть класс под названием Person с просто name

private class Person {
    public String name;

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

Код:

Gson g = new Gson();

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

Конечно, банда Gson должна быть на пути к классу .

JSON To Object (Библиотека Gson)

Допустим, у вас есть класс под названием Person с просто name

private class Person {
    public String name;

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

Код:

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

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

У вас должна быть библиотека gson в вашем пути к классам.

Извлечение одного элемента из 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

Использование Mapper объекта Jackson

Модель Pojo

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

Пример: String to Object

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

Пример: объект для строки

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

подробности

Необходима операция импорта:

import com.fasterxml.jackson.databind.ObjectMapper;

Зависимость Maven: jackson-databind

Экземпляр ObjectMapper

//creating one
ObjectMapper objectMapper = new ObjectMapper();
  • ObjectMapper является поточно
  • рекомендуется: иметь общий статический экземпляр

Десериализация:

<T> T readValue(String content, Class<T> valueType)  
  • valueType необходимо указать - возврат будет такого типа
  • Броски
    • IOException - в случае проблемы ввода-вывода низкого уровня
    • JsonParseException - если базовый ввод содержит недопустимый контент
    • JsonMappingException - если входная структура JSON не соответствует структуре объекта

Пример использования (jsonString - входная строка):

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

Метод сериализации:

String writeValueAsString (значение объекта)

  • Броски
    • JsonProcessingException в случае ошибки
    • Примечание: до версии 2.1 предложение бросков включено в IOException; 2.1 удалили его.

Итерация JSON

JSONObject над свойствами 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

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 - методы цепочки

Вы можете использовать цепочку методов при работе с JSONObject и JSONArray .

Пример 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

Если вам нужно добавить свойство с null значением, вы должны использовать предопределенный статический конечный JSONObject.NULL а не стандартную Java- null ссылку.

JSONObject.NULL - это контрольное значение, используемое для явного определения свойства с пустым значением.

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

Заметка

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

Что является явным нарушением контракта Java.equals() :

Для любого ненулевого опорного значения х, x.equals (NULL) должен возвращать ложь

JsonArray в список Java (Gson Library)

Вот простой JsonArray, который вы хотели бы преобразовать в Java ArrayList :

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

Теперь передайте список JsonArray 'следующему методу, который возвращает соответствующий 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;
}

Вы должны добавить следующую зависимость maven к вашему файлу 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>

Или у вас должен быть jar com.google.code.gson:gson:jar:<version> в вашем пути к классам.

Уничтожьте коллекцию JSON в коллекции объектов, используя Jackson

Предположим , у вас есть класс POJO Person

public class Person {
    public String name;

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

И вы хотите разобрать его в массив JSON или карту объектов Person. Из-за стирания типа вы не можете создавать классы List<Person> и Map<String, Person> непосредственно во время выполнения (и, следовательно, использовать их для десериализации JSON) . Чтобы преодолеть это ограничение, Джексон предлагает два подхода - TypeFactory и TypeReference .

TypeFactory

Подход, использованный здесь, заключается в использовании фабрики (и ее статической функции полезности) для создания вашего типа для вас. Требуемые параметры - это коллекция, которую вы хотите использовать (список, набор и т. Д.) И класс, который вы хотите сохранить в этой коллекции.

TypeReference

Тип ссылочного подхода кажется более простым, поскольку он экономит вам немного ввода и выглядит более чистым. TypeReference принимает параметр типа, в котором вы передаете желаемый тип List<Person> . Вы просто создаете экземпляр объекта TypeReference и используете его в качестве контейнера типа.

Теперь давайте посмотрим, как фактически десериализовать JSON в объект Java. Если ваш JSON отформатирован как массив, вы можете десериализовать его как список. Если существует более сложная вложенная структура, вам необходимо десериализовать карту. Мы рассмотрим примеры обоих.

Удаление десериализации массива JSON

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

Подход TypeFactory

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

Подход типа Type

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

Десериализация карты JSON

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

Подход TypeFactory

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

Подход типа Type

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

подробности

Используемая инструкция импорта:

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

Используемые экземпляры:

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

Заметка

Хотя подход TypeReference может выглядеть лучше, он имеет несколько недостатков:

  1. TypeReference должен быть TypeReference с использованием анонимного класса
  2. Вы должны предоставить общую экспликацию

Несоблюдение этого может привести к потере аргумента общего типа, что приведет к неудаче десериализации.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow