使用Jackson解析API响应遇UnrecognizedPropertyException问题求助
我来帮你搞定这个Jackson解析的问题~你遇到的com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Health"错误,核心原因是你的JSON结构和POJO类的层级/字段映射不匹配,下面给你两种直接可行的解决方案:
错误原因拆解
你的API响应JSON是外层包裹了一个"Health"根对象,里面才是实际的健康检查数据:
{ "Health": { "id": "abc_Server", "name": "ABC Request Service", "status": "GREEN", "dependencies": [ { "id": "DB", "name": "MySQL", "message": "Connection successful.", "status": "GREEN" } ] } }
而你直接用HealthResponse类去接收整个JSON,或者尝试的POJO结构没有正确对应这个层级,导致Jackson找不到匹配的"Health"字段。
方案一:利用@JsonRootName+开启反序列化根节点展开
你已经给HealthResponse加了@JsonRootName(value = "Health"),但之前只配置了序列化相关的WRAP_ROOT_VALUE,反序列化需要开启另一个特性。修改你的ObjectMapper配置:
ObjectMapper objectMapper = new ObjectMapper(); // 关键:开启反序列化时自动展开根节点 objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); // 序列化的配置按需保留即可,不影响反序列化 // objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false); try { InputStream response = healthCheckWebTarget.request(MediaType.APPLICATION_JSON).get(InputStream.class); HealthResponse healthResponse = objectMapper.readValue(response, HealthResponse.class); } catch(Exception e) { e.printStackTrace(); }
这样Jackson会自动识别@JsonRootName指定的根节点,把里面的内容直接映射到HealthResponse类中。
方案二:创建匹配JSON层级的根POJO类
如果你不想修改ObjectMapper的全局配置,可以创建一个根类来对应整个JSON结构,注意字段名要和JSON里的"Health"(大小写敏感)匹配,用@JsonProperty明确指定映射关系:
// 根类,对应整个JSON结构 public class HealthRoot { // 指定对应JSON里的大写"Health"字段 @JsonProperty("Health") private HealthResponse health; // getter和setter方法 public HealthResponse getHealth() { return health; } public void setHealth(HealthResponse health) { this.health = health; } } // 原HealthResponse类可以保留,不需要@JsonRootName public class HealthResponse { private String id; private String name; private String status; private List<Dependencies> dependencies; // getter和setter方法 } public class Dependencies { private String id; private String name; private String message; private String status; // getter和setter方法 }
然后反序列化时用根类接收,再取出内部的HealthResponse:
ObjectMapper objectMapper = new ObjectMapper(); try { InputStream response = healthCheckWebTarget.request(MediaType.APPLICATION_JSON).get(InputStream.class); HealthRoot healthRoot = objectMapper.readValue(response, HealthRoot.class); HealthResponse healthResponse = healthRoot.getHealth(); } catch(Exception e) { e.printStackTrace(); }
补充说明
你之前尝试的Health类无效,是因为类里的字段是小写的health,而JSON里是大写的"Health",Jackson默认大小写敏感,所以无法匹配,加上@JsonProperty("Health")就能解决这个问题。
内容的提问来源于stack exchange,提问作者Kiran

