Jackson反序列化异常:UnrecognizedPropertyException问题求助
解决Jackson反序列化UnrecognizedPropertyException的问题
看起来你遇到了一个典型的JSON结构与反序列化目标类不匹配的问题:从堆栈跟踪里的JSON片段能看出,你的接口响应是一个外层包含message、code、traceId等元数据的对象,真正的Country列表嵌套在data字段里,但你直接把整个JSON字符串反序列化成了Country类,这就导致Jackson试图把外层的message字段映射到Country类上,自然会抛出未识别字段的异常。
下面给你两种可行的解决方案:
方案1:创建匹配外层结构的响应类(推荐)
最规范的做法是创建一个外层响应类,完整匹配整个JSON的结构,再通过这个类获取内部的Country列表:
import java.util.List; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.*; @JsonInclude(JsonInclude.Include.NON_NULL) public class CountryResponse { @JsonProperty("message") private String message; @JsonProperty("code") private String code; @JsonProperty("traceId") private String traceId; @JsonProperty("origin") private String origin; @JsonProperty("details") private String details; @JsonProperty("timestamp") private String timestamp; @JsonProperty("data") private Data data; @JsonIgnore private Map<String, Object> additionalProperties = new HashMap<>(); // 所有字段的Getter和Setter方法 public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getTraceId() { return traceId; } public void setTraceId(String traceId) { this.traceId = traceId; } public String getOrigin() { return origin; } public void setOrigin(String origin) { this.origin = origin; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } @JsonAnyGetter public Map<String, Object> getAdditionalProperties() { return additionalProperties; } @JsonAnySetter public void setAdditionalProperty(String name, Object value) { additionalProperties.put(name, value); } // 内部类,用于映射data字段的结构 public static class Data { @JsonProperty("countries") private List<Country> countries; @JsonIgnore private Map<String, Object> additionalProperties = new HashMap<>(); public List<Country> getCountries() { return countries; } public void setCountries(List<Country> countries) { this.countries = countries; } @JsonAnyGetter public Map<String, Object> getAdditionalProperties() { return additionalProperties; } @JsonAnySetter public void setAdditionalProperty(String name, Object value) { additionalProperties.put(name, value); } } }
然后修改反序列化代码,把目标类型改成CountryResponse:
ObjectMapper objectMapper = new ObjectMapper(); // 假设jsonString是你的响应JSON字符串 CountryResponse response = objectMapper.readValue(jsonString, CountryResponse.class); // 获取Country列表 List<Country> countries = response.getData().getCountries();
方案2:直接解析JSON树提取目标数据
如果不想创建额外的响应类,也可以通过Jackson的JSON树API直接提取data里的countries部分再反序列化:
ObjectMapper objectMapper = new ObjectMapper(); // 先把JSON解析成树结构 JsonNode rootNode = objectMapper.readTree(jsonString); // 定位到countries节点 JsonNode countriesNode = rootNode.path("data").path("countries"); // 把节点反序列化成Country列表 List<Country> countries = objectMapper.readValue( countriesNode.traverse(), new com.fasterxml.jackson.core.type.TypeReference<List<Country>>(){} );
额外提示:不要盲目关闭未知字段检查
有些同学会想到通过配置ObjectMapper来忽略未知字段:
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
但这只是绕过错误,不是解决根本问题——因为你本来就不该把外层JSON映射到Country类,这种做法会隐藏结构不匹配的潜在问题,不推荐使用。
内容的提问来源于stack exchange,提问作者Randika Ratnayake
相关产品推荐
相关产品推荐

