Java Jackson自定义反序列化运行时异常已用JsonMappingException包装

Java Jackson自定义反序列化运行时异常已用JsonMappingException包装,java,json,exception,jackson,jackson-databind,Java,Json,Exception,Jackson,Jackson Databind,我有一个定制的反序列化程序,当id不是String类型时,除了CustomRuntimeException,但异常在我的测试结果中用JsonMappingException包装。在我将jackson-databind模块从2.5.x升级到2.10.x之前,测试用例运行良好。但它失败了: java.lang.Exception:意外异常, 应为,但 was 升级了jackson数据绑定后 @Override public Optional<String> deserialize(Jso

我有一个定制的反序列化程序,当
id
不是
String
类型时,除了
CustomRuntimeException
,但异常在我的测试结果中用
JsonMappingException
包装。在我将
jackson-databind
模块从
2.5.x
升级到
2.10.x
之前,测试用例运行良好。但它失败了:

java.lang.Exception
:意外异常, 应为
,但 was

升级了
jackson数据绑定后

@Override
public Optional<String> deserialize(JsonParser jsonParser,
                                    DeserializationContext deserializationContext) throws IOException {

  if (jsonParser.getCurrentToken() != JsonToken.VALUE_STRING) {
    throw new CustomRuntimeException("Id should be String");
  }
  return Optional.ofNullable(jsonParser.getValueAsString());
}
测试用例:

@Test(expected = CustomRuntimeException.class)
public void shouldThrowCustomRuntimeException() throws IOException {
  objectMapper.readValue("{ \"id\": 1245672564 }", IdSchema.class);
}
堆栈跟踪:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: id should be String (through reference chain: com.xxx["id"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:356)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1714)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:530)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:417)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1287)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4218)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3214)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3182)
    at com.xxx.shouldThrowCustomRuntimeException(xxx.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
    ... 16 more
Caused by: com.xxx.CustomRuntimeException: id should be String
您可以禁用以下功能:

确定
Jackson
code是否应捕获和包装的功能 异常(但绝不是错误!)以添加有关 是否存在问题的位置(输入内)。如果启用,大多数异常 将被捕获并重新抛出(特别是 IOException可以按原样传递,因为它们被声明为 可丢弃);这既方便又方便,因为所有例外情况都将被忽略 检查并声明,因此有更多上下文信息。 然而,有时调用应用程序可能只是想取消选中“raw” 按原样传递异常功能在默认情况下启用

例如:

ObjectMapper mapper = JsonMapper.builder()
        .disable(DeserializationFeature.WRAP_EXCEPTIONS)
        .build();
或者,您可以扩展
com.fasterxml.jackson.databind.JsonMappingException
而不是
RuntimeException

class CustomRuntimeException extends JsonMappingException {

    public CustomRuntimeException(Closeable processor, String msg) {
        super(processor, msg);
    }

    public CustomRuntimeException(Closeable processor) {
        super(processor, "Invalid argument is provided.");
    }
}
并从反序列化程序中以这种方式抛出:

if (p.getCurrentToken() != JsonToken.VALUE_STRING) {
    throw new CustomRuntimeException(p, "Id should be String");
}
在这两种情况下,您应该看到类似的情况:

Exception in thread "main" com.celoxity.CustomRuntimeException: Id should be String
 at [Source: (File); line: 1, column: 9] (through reference chain: com.example.IdSchema["id"])
    at com.example.IdJsonDeserializer.deserialize(JsonTypeInfoApp.java:36)
    at com.example.IdJsonDeserializer.deserialize(JsonTypeInfoApp.java:31)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)
您可以禁用以下功能:

确定
Jackson
code是否应捕获和包装的功能 异常(但绝不是错误!)以添加有关 是否存在问题的位置(输入内)。如果启用,大多数异常 将被捕获并重新抛出(特别是 IOException可以按原样传递,因为它们被声明为 可丢弃);这既方便又方便,因为所有例外情况都将被忽略 检查并声明,因此有更多上下文信息。 然而,有时调用应用程序可能只是想取消选中“raw” 按原样传递异常功能在默认情况下启用

例如:

ObjectMapper mapper = JsonMapper.builder()
        .disable(DeserializationFeature.WRAP_EXCEPTIONS)
        .build();
或者,您可以扩展
com.fasterxml.jackson.databind.JsonMappingException
而不是
RuntimeException

class CustomRuntimeException extends JsonMappingException {

    public CustomRuntimeException(Closeable processor, String msg) {
        super(processor, msg);
    }

    public CustomRuntimeException(Closeable processor) {
        super(processor, "Invalid argument is provided.");
    }
}
并从反序列化程序中以这种方式抛出:

if (p.getCurrentToken() != JsonToken.VALUE_STRING) {
    throw new CustomRuntimeException(p, "Id should be String");
}
在这两种情况下,您应该看到类似的情况:

Exception in thread "main" com.celoxity.CustomRuntimeException: Id should be String
 at [Source: (File); line: 1, column: 9] (through reference chain: com.example.IdSchema["id"])
    at com.example.IdJsonDeserializer.deserialize(JsonTypeInfoApp.java:36)
    at com.example.IdJsonDeserializer.deserialize(JsonTypeInfoApp.java:31)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)

谢谢,但我认为在Jackson databind 2.5中,wrap_异常在默认情况下也是正确的,不确定升级到2.10后行为为什么会改变谢谢,但我认为在Jackson databind 2.5中,wrap_异常在默认情况下也是正确的,不确定升级到2.10后行为为什么会改变