You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jackson自定义反序列化器中抛出可被外层捕获的自定义异常

问题原因

Jackson默认启用DeserializationFeature.WRAP_EXCEPTIONS配置,会将反序列化过程中抛出的异常统一包装为JsonMappingException,对于直接继承IOException的自定义异常,默认包装逻辑不会将原始自定义异常填充为JsonMappingException的cause,因此外层无法通过getCause()获取到自定义异常实例。

解决方案一:调整反序列化器抛出逻辑(无全局配置变更,推荐)

直接在抛出自定义异常时,手动构造JsonMappingException并传入自定义异常作为cause,自定义反序列化器代码修改如下:

@Override
public MyClass deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    CustomException customEx = new CustomException("TestException", 1);
    // 手动包装自定义异常为JsonMappingException,填充cause
    throw new JsonMappingException(jsonParser, customEx.getMessage(), customEx);
}

外层捕获后即可从cause中获取自定义异常:

catch (JsonMappingException e) {
    if (e.getCause() instanceof CustomException) {
        CustomException customEx = (CustomException) e.getCause();
        // 业务逻辑处理,可直接获取自定义异常的code字段
        int code = customEx.getCode();
    }
}

解决方案二:关闭Jackson异常包装全局配置

如果你希望反序列化器抛出的IOException直接透传到外层,不需要Jackson包装,可以给ObjectMapper关闭DeserializationFeature.WRAP_EXCEPTIONS配置:

ObjectMapper mapper = new ObjectMapper();
// 关闭异常自动包装配置
mapper.configure(DeserializationFeature.WRAP_EXCEPTIONS, false);

配置后外层可以直接捕获到原始的CustomException:

try {
    MyClass myClass = mapper.readValue(json, MyClass.class);
} catch (CustomException e) {
    // 直接处理自定义异常
    int code = e.getCode();
} catch (IOException e) {
    // 处理其他IO异常
}

注意事项

  • 示例代码中new ObjectMapped()是笔误,正确类名是ObjectMapper
  • 关闭全局异常包装后,所有反序列化过程中抛出的IOException都会直接透传,不会被包装为JsonMappingException,需要评估对现有逻辑的影响

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:45:04