【问题标题】:JSON to Java object - Unrecognized field, not marked as ignorableJSON 到 Java 对象 - 无法识别的字段,未标记为可忽略
【发布时间】:2018-11-22 12:26:49
【问题描述】:

我正在尝试将以下 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 字段上,但我不知道如何解决这个问题(here 的解决方案也对我不起作用)。

问题

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

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!投票赞成!将另一个答案标记为已回答更完整
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      问题在于您的 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 注释 告诉 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; }
        }
        

        在你的其他 Java 类中以同样的方式 (Links, Meta, Data, ...)

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

      【讨论】:

      • 谢谢!注释解决了我的问题。标记为已回答并投票赞成。
      【解决方案4】:

      我收到此错误,因为我不打算将所有 JSON 字段映射到我的 POJO,但只映射了一些。因此,它要求我将它们标记为忽略。以下示例展示了这个想法:

      @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 +"]";
      }
      

      另一方面,我的 Json 响应执行了 10 多个字段。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 2011-05-28
        • 1970-01-01
        • 2013-10-11
        相关资源
        最近更新 更多