Spring中使用Jackson解析JSON时Ad对象为空问题排查
问题:Jackson解析JSON时Ad对象的ad属性为空
原始JSON数据
{ "ads": [ { "228029_228029": { "ad_id": "228029", "duration": 10, "m3u8_text": { "_1280p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:7\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.120000,\n_1280p_0000.ts\n#EXTINF:2.880000,\n_1280p_0001.ts\n#EXT-X-ENDLIST\n", "_320p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:7\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.120000,\n_320p_0000.ts\n#EXTINF:2.880000,\n_320p_0001.ts\n#EXT-X-ENDLIST\n" } } }, { "228845_228845": { "ad_id": "228845", "duration": 24, "m3u8_text": { "_1280p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:8\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.840000,\n_1280p_0000.ts\n#EXTINF:6.880000,\n_1280p_0001.ts\n#EXTINF:6.680000,\n_1280p_0002.ts\n#EXTINF:2.600000,\n_1280p_0003.ts\n#EXT-X-ENDLIST\n", "_320p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:8\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.840000,\n_320p_0000.ts\n#EXTINF:6.880000,\n_320p_0001.ts\n#EXTINF:6.680000,\n_320p_0002.ts\n#EXTINF:2.600000,\n_320p_0003.ts\n#EXT-X-ENDLIST\n" } } } ], "total_duration": 80 }
实体类定义
AdsResponse类
@JsonIgnoreProperties(ignoreUnknown = true) public class AdsResponse { @JsonProperty("ads") List<Ad> ads; @JsonProperty("total_duration") long totalDuration; }
Ad类
public class Ad { Map<String,AdInfo> ad; }
AdInfo类
public class AdInfo { @JsonProperty("m3u8_text") AdManifest adManifest; int duration; @JsonProperty("ad_id") String adId; }
AdManifest类
public class AdManifest { @JsonProperty("_1280p") String _1280p; @JsonProperty("_320p") String _320p; }
解析代码与问题现象
解析代码:
AdsResponse response = new ObjectMapper().readValue( res, AdsResponse.class);
解析结果:
AdsResponse{ads=[Ad{ad=null}, Ad{ad=null}], totalDuration=80}
问题原因与解决方案
问题根源
JSON数组ads中的每个元素是带动态键名的对象(比如"228029_228029"),但你定义的Ad类里的ad字段没有任何Jackson注解,且键名不是固定的"ad",Jackson无法识别要把这个动态键的对象映射到ad字段上,因此ad属性为空。
解决方案
有两种简单的修改方式:
方案一:移除Ad类,直接使用Map接收动态键
修改AdsResponse类的ads字段类型为List<Map<String, AdInfo>>,让Jackson直接把每个动态键对象映射为Map:
@JsonIgnoreProperties(ignoreUnknown = true) public class AdsResponse { @JsonProperty("ads") List<Map<String, AdInfo>> ads; @JsonProperty("total_duration") long totalDuration; }
方案二:给Ad类添加@JsonAnySetter处理动态键
如果需要保留Ad类,在Ad类中添加@JsonAnySetter注解的方法,让Jackson自动将动态键值对注入ad Map:
public class Ad { Map<String, AdInfo> ad = new HashMap<>(); @JsonAnySetter public void addAd(String key, AdInfo value) { ad.put(key, value); } }
两种方案都能解决解析后ad属性为空的问题,根据你的代码结构选择即可。
内容的提问来源于stack exchange,提问作者WISHY
相关产品推荐
相关产品推荐

