简体   繁体   English

杰克逊:反序列化自定义异常

[英]jackson: deserialize a custom exception

I am trying to get Jackson to deserialize a JSON-encoded custom exception, and it fails if the exception disables the stacktrace. 我试图让杰克逊反序列化JSON编码的自定义异常,如果异常禁用了堆栈跟踪,它将失败。

Working example: 工作示例:

public static class CustomException extends Exception {
    public CustomException(String msg) {
        super(msg);
    }
}

@Test
public void testSerializeAndDeserializeCustomException() throws Exception {
    log.info("Test: testSerializeAndDeserializeCustomException");

    CustomException ex1 = new CustomException("boom");
    ObjectMapper om = new ObjectMapper();

    String json = om.writerFor(CustomException.class).writeValueAsString(ex1);
    assertNotNull(json);
    log.info("JSON: {}", json);

    CustomException ex2 = om.readerFor(CustomException.class).readValue(json);
    assertNotNull(ex2);
    assertEquals(ex2.getMessage(), ex1.getMessage());
}

Not working example: 不起作用的示例:

public static class CustomNoStackException extends Exception {
    public CustomNoStackException(String msg) {
        super(msg, null, true, false);
    }
}

@Test
public void testSerializeAndDeserializeCustomNoStackException() throws Exception {
    log.info("Test: testSerializeAndDeserializeCustomNoStackException");

    CustomNoStackException ex1 = new CustomNoStackException("boom");
    ObjectMapper om = new ObjectMapper();

    String json = om.writerFor(CustomNoStackException.class).writeValueAsString(ex1);
    assertNotNull(json);
    log.info("JSON: {}", json);

    CustomNoStackException ex2 = om.readerFor(CustomNoStackException.class).readValue(json);
    assertNotNull(ex2);
    assertEquals(ex2.getMessage(), ex1.getMessage());
}

In the second case, readValue(json) actually throws the CustomNoStackException wrapped in an IOException . 在第二种情况下, readValue(json)实际上引发了包装在IOExceptionCustomNoStackException

What am I doing wrong? 我究竟做错了什么?

When an Exception is initialized without a cause , it marks itself as the cause . Exception初始化时没有cause ,它将自身标记为cause

private Throwable cause = this;

It uses that as a sentinel value to indicate that it has no cause. 它使用该值作为前哨值来指示它没有原因。 initCause only lets you change the cause if it's not itself. initCause仅允许您更改cause ,而不是cause本身。

Your CustomNoStackException constructor is initializing the cause with null , breaking the sentinel value. 您的CustomNoStackException构造函数正在使用null初始化cause ,从而破坏了哨兵值。 When Jackson later tries to call initCause method because of the 由于以下原因,当Jackson稍后尝试调用initCause方法时

"cause":null

pair in the JSON, initCause throws an exception saying you can't overwrite an exception's cause (this is nested in the JsonMappingException ). 在JSON对中, initCause引发异常,表示您不能覆盖异常的cause (此嵌套在JsonMappingException )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM