JSON 到 Java 对象 - 无法识别的字段,未标记为可忽略

Hey*_*nge 4 java json jackson

我正在尝试将以下 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
  }
}
Run Code Online (Sandbox Code Playgroud)

使用以下 DTO(为简洁起见,尚未发布引用的类)。

{
  "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
  }
}
Run Code Online (Sandbox Code Playgroud)

将 DTO 转换为 Java 对象的代码是:

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; }
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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;
}
Run Code Online (Sandbox Code Playgroud)

我尝试了不同的方法来解决这个问题,例如:

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"])
Run Code Online (Sandbox Code Playgroud)

也:

@JsonRootName(value = "data")
Run Code Online (Sandbox Code Playgroud)

但我要么遇到同样的问题,要么没有问题,但只有TransactionDTO包含null值。

我想问题是Data领域,但我不知道如何解决这个问题(这里的解决方案对我也不起作用)。

问题

  1. 知道如何解决这个问题吗?
  2. 访问器案例是否应该反映 JSON 中的案例?

psm*_*gin 6

Jackson 默认区分大小写。尝试这个:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
Run Code Online (Sandbox Code Playgroud)


Tho*_*sch 5

问题是您的 JSON 属性名称(例如"Data")与您的 Java 属性名称(例如 )不匹配data。除了 @psmagin 的答案之外,还有两个替代选项可以修复它:

  1. 保持 Java 代码不变。并且在 JSON 内容中将所有键( 留下的字符串:)从第一个大写更改为第一个小写:

    {
       "data":[
       {
         "accountId":"2009852923",
         "currency":"EUR",
         "nickname":"SA 01",
         "account":{
           "schemeName":"BBAN",
           "name":"SA 01",
           "identification":"2009852923"
       },
       ....
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 保持 JSON 内容不变。在您的 Java 代码中,使用@JsonProperty注释告诉 Jackson 您的 Java 属性对应的 JSON 属性名称:

    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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    并以同样的方式在您的其他 Java 类中(LinksMetaData、 ...)

我更喜欢第一个选项,因为首字母小写的属性名称是 JSON 和 Java 中既定的最佳实践。


Fed*_*man 5

我使用这种方法解决了类似的问题

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Run Code Online (Sandbox Code Playgroud)