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注解即可解决,有两种兼容不同版本的写法:
- 注解标记在字段上(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; } - 注解标记在自定义方法上(兼容所有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
相关产品推荐
相关产品推荐

