简体   繁体   中英

JSON to Java object - Unrecognized field, not marked as ignorable

I'm trying to transform the following JSON into a java Object.

{
  "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
  }
}

Using the following DTO (for brevity, the referenced classes haven't been posted).

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

The code to transform the DTO to a Java object being:

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

I'm getting this error:

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"])

I tried different approach to solve this issue such as:

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

As well as:

@JsonRootName(value = "data")

But I either get the same problem, or no problems, but the TransactionDTO containing null values only.

I guess the problem is the Data field, but I don't know how to fix this problem (the solutions here don't work for me neither).

Questions

  1. Any idea how to fix this problem ?
  2. Should the accessors case reflect the case in the JSON ?

Jackson is case sensitive by default. Try this:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

I solved a similar problem using this aproach

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

The problem is that your JSON property names (eg "Data" ) don't match your Java property names (eg data ). Besides @psmagin's answer there are two alternative options to fix it:

  1. Keep your Java code unchanged. And in the JSON contents change all keys (the strings left from the : ) from first-uppercase to first-lowercase:

     { "data":[ { "accountId":"2009852923", "currency":"EUR", "nickname":"SA 01", "account":{ "schemeName":"BBAN", "name":"SA 01", "identification":"2009852923" }, .... }
  2. Keep the JSON contents unchanged. And in your Java-code use @JsonProperty annotations to tell Jackson the corresponding JSON property-names of your Java properties:

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

    and in the same manner in your other Java classes ( Links , Meta , Data , ...)

I would prefer the first option, because property names with first-lowercase are the established best practice in JSON and Java.

I got this error as I did not intend to map all the JSON fields to my POJO, but only a few. Consequently, it was asking me to mark them ignore. Following sample presents the idea:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Book {

@JsonProperty("kind")
private String kind;

@JsonProperty("id")
private String id;

@JsonProperty("volumeInfo")
private BookInfo bookInfo;

@Override
public String toString() {
    return "ClassPojo [kind = " + kind + ", id = " + id + ", bookInfo = " + bookInfo +"]";
}

On the other hand, my Json response carried out 10+ fields.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM