如何统计UnrecognizedPropertyException抛出次数及捕获错误属性名
解决UnrecognizedPropertyException的属性跟踪与计数问题
我来帮你搞定这个问题,你的代码目前有两个核心问题:计数器无法累计错误次数,以及没法完整获取所有拼写错误的属性名,下面一步步给你解决:
1. 为什么计数器总是返回1?
你的counter是局部变量,每次执行这段代码时都会被重新初始化为0;而且默认情况下Jackson遇到第一个未识别属性就会抛出异常,不会继续解析后续的错误属性。如果是多次请求的场景,局部变量也没法保留之前的计数结果。
解决方法:把计数相关的变量提升为类的成员变量(或静态变量),这样它的值会在多次请求/异常捕获中持续保留。
2. 如何正确获取所有拼写错误的属性名?
默认的UnrecognizedPropertyException只会携带第一个未识别的属性名,但如果JSON里有多个拼写错误的属性,你需要先配置ObjectMapper让它收集所有未识别属性,而不是遇到第一个就终止解析。
完整解决方案代码(推荐)
这个方案用Map跟踪每个错误属性的出现次数,同时能捕获所有未识别的属性:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.Map; public class JsonErrorTracker { // 用Map存储每个错误属性的出现次数,比单个计数器更灵活 private Map<String, Integer> errorPropertyCount = new HashMap<>(); private ObjectMapper objectMapper; public JsonErrorTracker() { objectMapper = new ObjectMapper(); // 禁用"遇到第一个未知属性就抛出异常"的默认行为 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 添加自定义处理器,拦截所有未识别的属性 objectMapper.addHandler(new DeserializationProblemHandler() { @Override public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException, JsonProcessingException { // 累计该属性的错误次数 errorPropertyCount.put(propertyName, errorPropertyCount.getOrDefault(propertyName, 0) + 1); // 返回true表示已处理该属性,继续解析后续内容 return true; } }); } public void parseJsonFromUrl(String urlStr) throws IOException { URL url = new URL(urlStr); JsonContainer[] jc = objectMapper.readValue(url, JsonContainer[].class); // 此处可处理解析后的对象 } // 获取错误属性的统计结果(返回副本避免外部修改原数据) public Map<String, Integer> getErrorPropertyCount() { return new HashMap<>(errorPropertyCount); } // 你的JsonContainer实体类(示例) static class JsonContainer { // 这里定义正确的属性,比如: private String userName; // getter、setter方法省略 } public static void main(String[] args) { JsonErrorTracker tracker = new JsonErrorTracker(); try { tracker.parseJsonFromUrl("sample_url"); } catch (IOException e) { e.printStackTrace(); } // 打印统计结果 System.out.println("错误属性统计:"); tracker.getErrorPropertyCount().forEach((prop, count) -> System.out.println(prop + ": " + count + "次")); } }
简化版(仅捕获第一个未识别属性)
如果只需要处理第一个出现的错误属性,修改你的原有代码即可:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; import java.net.URL; import java.util.HashMap; import java.util.Map; public class SimpleErrorTracker { // 成员变量存储计数,保留多次请求的状态 private Map<String, Integer> errorPropertyCount = new HashMap<>(); private ObjectMapper objectMapper = new ObjectMapper(); public void parseJson() { try { URL url = new URL("sample_url"); JsonContainer[] jc = objectMapper.readValue(url, JsonContainer[].class); } catch (UnrecognizedPropertyException e) { String wrongProp = e.getPropertyName(); // 累计该属性的错误次数 errorPropertyCount.put(wrongProp, errorPropertyCount.getOrDefault(wrongProp, 0) + 1); // 打印或记录错误属性名 System.out.println("发现未识别属性:" + wrongProp); } catch (Exception e) { // 处理其他异常 e.printStackTrace(); } } public Map<String, Integer> getErrorPropertyCount() { return new HashMap<>(errorPropertyCount); } static class JsonContainer { // 你的类属性 } }
注意:这个版本只能捕获第一个未识别的属性,Jackson遇到第一个错误就会停止解析。
内容的提问来源于stack exchange,提问作者Harish Harry
相关产品推荐
相关产品推荐

