You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RestTemplate Json注解不生效 无法反序列化带动态key的JSON结构

问题场景

需要反序列化结构如下的JSON数据:

{
    "header": {
         "type": "esummary",
         "version": "0.3"
    },
    "result": {
         "22807455": {
              "uid": "22807455",
              "pubdate": "2012 Jul",
              "epubdate": ""
         },
        "uids": [
              "22807455"
        ]
  }
}

初始定义的两个Java类代码如下:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class PubmedResponse {

    @JsonProperty("header")
    PubmedHeader header;

    @JsonProperty("result")
    PubmedResultMap resultMap;

}

@Getter
@Setter
@JsonIgnoreProperties
public class PubmedResultMap implements PubmedInfo{

    Map<String, PubmedResult> results;

    @JsonProperty("uids")
    List<String> uids;
}

反序列化时PubmedResultMap无法识别22807455这类动态key,没有固定属性名可以直接映射到results字段。

解决方法

这是Jackson反序列化「同层级同时存在固定属性+动态key属性」场景的典型问题,用@JsonAnySetter注解即可解决,有两种兼容不同版本的写法:

  1. 注解标记在字段上(Jackson 2.12及以上版本支持)
    直接给results字段加@JsonAnySetter注解,所有没有匹配到固定属性(比如uids)的键值对,都会自动存入这个Map中:
    @Getter
    @Setter
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class PubmedResultMap implements PubmedInfo{
    
        @JsonAnySetter
        Map<String, PubmedResult> results = new HashMap<>();
    
        @JsonProperty("uids")
        List<String> uids;
    }
    
  2. 注解标记在自定义方法上(兼容所有Jackson版本)
    如果使用的Jackson版本较低,可以写一个专门接收动态属性的方法,把非固定字段手动存入results:
    @Getter
    @Setter
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class PubmedResultMap implements PubmedInfo{
    
        Map<String, PubmedResult> results = new HashMap<>();
    
        @JsonProperty("uids")
        List<String> uids;
    
        @JsonAnySetter
        public void putDynamicField(String key, PubmedResult value) {
            // 可按需增加过滤逻辑,避免非文献字段存入map
            if (value != null && value.getUid() != null) {
                results.put(key, value);
            }
        }
    }
    

注意事项

  • 记得给results字段初始化默认值,避免反序列化过程中出现空指针
  • 如果后续需要把Java对象再序列化为原JSON结构,可以在results的getter方法上加@JsonAnyGetter注解,序列化时map中的键值对会直接平铺到result节点下,和原结构完全一致
  • 确保PubmedResult类定义了uid、pubdate、epubdate等对应字段,字段名和JSON属性名匹配即可正常反序列化

内容的提问来源于stack exchange,提问作者ypriverol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 04:03:35