JSON в Java POJO не работает для простой структуры? - PullRequest
0 голосов
/ 12 марта 2019

JSON:

{
  "246": {
    "test1": "one" 
  },
  "355": {
    "test2": "two"
  }
}

Java POJO

class POJO{
  private HashMap<String, SubPojo> subMap;

  @JsonAnySetter
  public void addToMap(String key, SubPojo val){ subMap.put(key, value); }
}

class SubPojo{
  private HashMap<String, String> map; 
  @JsonAnySetter
  public void addToMap(String key, String val) { map.put(key, value);}
}

В моем коде я делаю: (используя Джексон )

POJO testing = (new ObjectMapper()).convertValue("path/to/json", POJO.class);

Я получаю исключение, говорящее:

"Unrecognized field `246`..."

Куда я иду не так?

Ответы [ 3 ]

0 голосов
/ 12 марта 2019

converValue метод используется для преобразования объектов. См JavaDoc:

удобный метод для двухэтапного преобразования из заданного значения, в экземпляр данного типа значения, если (но только если!) преобразование необходимо. Если данное значение уже имеет запрошенный тип, возвращается значение как есть. Этот метод функционально похож на первую сериализацию значение в JSON, а затем привязать данные JSON к значению данного типа, но должен быть более эффективным, поскольку полная сериализация не происходить. Тем не менее, те же конвертеры (сериализаторы, десериализаторы) будут использоваться как для привязки данных, то есть для конфигурации объекта сопоставления объектов работы.

Например, вы можете «конвертировать» File в String следующим образом:

mapper.convertValue(jsonFile, String.class)

Где jsonFile - это экземпляр класса File. Пример результата может быть: path/to/json.

Для десериализации JSON полезных данных используйте один из readValue методов семейства.

Вы можете создать свой POJO с аннотированным конструктором JsonCreator:

class Pojo {

    private final Map<String, SubPojo> map;

    @JsonCreator
    public Pojo(Map<String, SubPojo> map) {
        this.map = map;
    }

    public Map<String, SubPojo> getMap() {
        return map;
    }

    @Override
    public String toString() {
        return "Pojo{" +
                "map=" + map +
                '}';
    }
}

class SubPojo {

    private Map<String, String> map;

    @JsonCreator
    public SubPojo(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "SubPojo{" +
                "map=" + map +
                '}';
    }
}

И простое использование. Для чтения JSON из файла используйте readValue метод:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        Pojo map = mapper.readValue(jsonFile, Pojo.class);
        System.out.println(map);
    }
}

Над кодом напечатано:

Pojo{map={246=SubPojo{map={test1=one}}, 355=SubPojo{map={test2=two}}}}

Если вы хотите остаться с вашей моделью данных, используйте аннотацию JsonAnySetter. Ваша модель данных может выглядеть так:

class Pojo {
    private Map<String, SubPojo> subMap = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, SubPojo value) {
        subMap.put(key, value);
    }

    @Override
    public String toString() {
        return "POJO{" +
                "subMap=" + subMap +
                '}';
    }
}

class SubPojo {
    private Map<String, String> map = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, String value) {
        map.put(key, value);
    }

    @Override
    public String toString() {
        return "SubPojo{" +
                "map=" + map +
                '}';
    }
}

Приведенный выше пример использования печатает:

POJO{subMap={355=SubPojo{map={test2=two}}, 246=SubPojo{map={test1=one}}}}
0 голосов
/ 12 марта 2019

Вам не нужно создавать какие-либо классы POJO для анализа этого текста JSON, так как он может быть проанализирован в Map<String, Map<String, String>>.

. Вам нужно будет использовать TypeReference, чтобы предотвратить потерюаргументы универсального типа.

Map<String, Map<String, String>> data = new ObjectMapper()
        .readValue(new File("test.json"),
                   new TypeReference<Map<String, Map<String, String>>>() {});

Печать этой карты data с использованием текста JSON в вопросе покажет:

{246={test1=one}, 355={test2=two}}
0 голосов
/ 12 марта 2019

Примерно так:

public class Pojo {
    private Map<String,Object> map = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, Object value) {
        this.map.put(key, value);
    }

    @JsonAnyGetter
    public Map<String,Object> getMap() {
        return map;
    }
}

Есть статья о Baeldung , которая охватывает различные аннотации Джексона, включая эту, и некоторые основы Jackson wiki .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...