Объект JSON to Java - нераспознанное поле, не помеченное как игнорируемое - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь преобразовать следующий JSON в объект Java.

{
  "Data":[
    {
      "AccountId":"2009852923",
      "Currency":"EUR",
      "Nickname":"SA 01",
      "Account":{
        "SchemeName":"BBAN",
        "Name":"SA 01",
        "Identification":"2009852923"
      },
      "Servicer":{
        "SchemeName":"BICFI",
        "Identification":"FNBSZAJJ"
      }
    },
    {
      "AccountId":"1028232942",
      "Currency":"EUR",
      "Nickname":"FNBCREDIT",
      "Account":{
        "SchemeName":"BBAN",
        "Name":"FNBCREDIT",
        "Identification":"1028232942"
      },
      "Servicer":{
        "SchemeName":"BICFI",
        "Identification":"FNBSZAJJ"
      }
    }
  ],
  "Links":{
    "self":"http://localhost:3000/api/open-banking/accounts/1009427721/transactions"
  },
  "Meta":{
    "total-pages":1
  }
}

Используя следующий DTO (для краткости ссылочные классы не были опубликованы).

public class TransactionDTO {
    private Data[] data;
    private Links links;
    private Meta meta;
    public Data[] getData () {  return data; }
    public void setData (Data[] data) { this.data = data; }
    public Links getLinks () { return links; }
    public void setLinks (Links links) { this.links = links; }
    public Meta getMeta () { return meta; }
    public void setMeta (Meta meta) { this.meta = meta; }
}

Код для преобразования DTO в объект Java:

private TransactionDTO marshall(String accountTransactionsJSON) {
    ObjectMapper objectMapper = new ObjectMapper();
    TransactionDTO transactionDTO = null;
    try {
        transactionDTO = objectMapper.readValue(accountTransactionsJSON, TransactionDTO.class);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return transactionDTO;
}

Я получаю эту ошибку:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Data" (class xxx.dto.TransactionDTO), not marked as ignorable (3 known properties: "links", "data", "meta"])
 at [Source: java.io.StringReader@48f43b70; line: 2, column: 11] (through reference chain: xxx.dto.TransactionDTO["Data"])

Я пробовал другой подход для решения этой проблемы, такой как:

objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

А также:

@JsonRootName(value = "data")

Но у меня либо та же проблема, либо проблем нет, но TransactionDTO содержит только значения null.

Полагаю, проблема в поле Data, но я не знаю, как решить эту проблему (решения здесь у меня тоже не работают).

Вопросы

  1. Есть идеи, как решить эту проблему?
  2. Должен ли случай со средствами доступа отражать случай в JSON?

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Проблема в том, что ваши имена свойств JSON (например, "Data") не совпадают с именами ваших свойств Java (например, data).Помимо ответа @ psmagin, есть два альтернативных варианта, чтобы исправить это:

  1. Оставьте свой код Java без изменений.А в содержимом JSON измените все ключи (строки, оставленные от :) с первого на верхний регистр на первый-нижний регистр:

    {
       "data":[
       {
         "accountId":"2009852923",
         "currency":"EUR",
         "nickname":"SA 01",
         "account":{
           "schemeName":"BBAN",
           "name":"SA 01",
           "identification":"2009852923"
       },
       ....
    }
    
  2. Оставьте содержимое JSON без изменений.И в своем Java-коде используйте аннотации @JsonProperty, чтобы сообщить Джексону соответствующие имена свойств JSON ваших свойств Java:

    public class TransactionDTO {
        private @JsonProperty("Data") Data[] data;
        private @JsonProperty("Links") Links links;
        private @JsonProperty("Meta") Meta meta;
        public Data[] getData () {  return data; }
        public void setData (Data[] data) { this.data = data; }
        public Links getLinks () { return links; }
        public void setLinks (Links links) { this.links = links; }
        public Meta getMeta () { return meta; }
        public void setMeta (Meta meta) { this.meta = meta; }
    }
    

    и таким же образом в других ваших классах Java(Links, Meta, Data, ...)

Я бы предпочел первый вариант, потому что имена свойств с первым-нижним регистром являются признанной лучшей практикой в ​​JSONи Java.

0 голосов
/ 22 ноября 2018

Джексон чувствителен к регистру по умолчанию.Попробуйте это:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...