Создать универсальный java mapper для json string - PullRequest
0 голосов
/ 03 мая 2018

Я работаю над проектом Spring-boot, где я получаю другой формат Json String. Моя цель - преобразовать эти строки Json в класс Unified Java.

Я могу получить много вариантов этого Json:

{ "id" : "someId", "type" : "temperature", "value" : 21.0 }

Например, один вариант может выглядеть следующим образом:

{ "id" : "someId", "data" : { "type": "temp", "val" : 21.0 }, "location": "here" }

Так что эти 2 Json должны быть отображены в один и тот же класс Java. У меня уже есть 2 решения:

Первое решение

1) Создайте определенный класс Java для каждого Json, который я могу получить

2) Создайте функцию, которая принимает этот конкретный объект и возвращает Unified Java Class

Второй раствор

1) Создать JsonNode со строкой Json

2) Для каждого ключа попытайтесь сопоставить его с полем Unified Java Class. Но мы должны принять во внимание все возможные ключи узла, такие как «value» или «val».

Как лучше всего решить эту проблему? Я ищу решение, которое можно было бы легко поддерживать.

Редактировать : Я уже использую Джексона, но моя проблема состоит в том, чтобы отобразить этот объект Json в универсальный класс Java независимо от Json

Редактировать 2 : Unified Java Class - это модель класса, которая уже существует и используется для хранения информации в нашей базе данных. Поэтому, чтобы поместить информацию в нашу базу данных, я должен преобразовать каждый полученный json в этот унифицированный формат

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Я вижу следующие решения. Например. вы используете Jackson для разбора JSON вы можете объявить свой пользовательский ObjectMapper:

ObjectMapper mapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

Этот преобразователь содержит дополнительные параметры, позволяющие игнорировать неизвестные свойства.

  1. У вас Map<String, Object> в качестве класса назначения. Это magic key и работает всегда. Против : у вас нет проверки json, и вам нужно добавить много постоянных ключей, чтобы прочитать это.

Пример:

public static <T> Map<String, T> readMap(String json) throws NGPException {
    if (json == null) {
        return null;
    }

    ObjectReader reader = JSON_MAPPER.readerFor(Map.class);
    MappingIterator<Map<String, T>> it = reader.readValues(json);

    if (it.hasNextValue()) {
        Map<String, T> res = it.next();
        return res.isEmpty() ? Collections.emptyMap() : res;
    }

    return Collections.emptyMap();
}

Клиент:

Map<String, Object> map = readMap("json string");
String id = (String)map.getOrDefault("id", null);
  1. Второй способ - создать один общий класс, содержащий все возможные переменные. Кроме того, вы должны установить опцию, чтобы Джексон игнорировал неизвестные поля. В этом случае существующие поля будут использоваться Джексоном.

Пример:

public static <T> T read(String json, Class<T> clazz) throws NGPException {
    return mapper.readerFor(clazz).readValue(json);
}

class Response {
    private String id;
    private String type;
    private Double value;
    private String location;
    private Data data;

    public class Data {
        private String type;
        private String temp;
        private Double value;
    }
}

Клиент:

Response response = read("json string", Response.class);
0 голосов
/ 03 мая 2018

Я обычно использую GSon от Google. Это действительно полезно. Проверьте gson.fromJson (yourJsonString) в вашем случае.

Вы можете легко использовать

Gson gson = new Gson();    
Data data = gson.fromJson(jsonString, Data.class);
...