17

Jackson 的 ObjectMapper#readValue成员抛出了三个已检查的异常:

IOException 
JsonParseException 
JsonMappingException

JsonParseExceptionJsonMappingException扩展IOException。我想包装前面提到的两个子类并抛出我自己的自定义异常,但是,IOException正在检查的基类 要求我也捕获或抛出它。

对我来说,把它扔到调用层是没有意义的IOException,但是,如果我把它隐藏起来,那是一种气味。我最初的想法是不捕获它并将其留给调用者/运行时异常机制来处理它......但是,我不想强​​迫调用者捕获或指定。

在这种情况下怎么办?

4

4 回答 4

15

简短的回答:如果你处理 IO,你处理IOExceptions。如果你不处理 IO,那么IOExceptions 应该变成未经检查的异常,因为它们是错误代码的症状。


更长的答案:

readValue总是需要一个JsonParser,它可以包裹在 IO 周围(例如一个文件或一个 URL)。如果您正在处理 IO,则无法处理IOExceptions,您应该处理它们或以某种方式重新抛出/传递它们。在 IO 期间任何事情都可能发生,您应该准备好处理异常。

但是,如果您确定您的JsonParser实例不使用 IO(例如,您曾经JsonFactory#createJsonParser(java.lang.String)在字符串上创建 JSON 解析器),您可能会假设IOException您收到的任何 s 都是错误,无论是在您的代码中还是在 Jackson 中。通常,抛出未经检查的异常是处理它的正确方法:

ObjectMapper om = new ObjectMapper(/* whatever */);
JsonParser jp = JsonFactory.createJsonParser("{ \"foo\": \"bar\" }");
try {
    return om.readValue(jp);
} catch (IOException e) {
    throw new AssertionError("An IOException occurred when this was assumed to be impossible.");
}

注意:我的 Java 生锈了,而且我从未使用过 Jackson,所以将上面的代码块视为伪代码。

无论如何,您永远不需要声明AssertionErrorin throws,因为它们是未经检查的异常。所有属于java.lang.RuntimeExceptionjava.lang.Error不需要明确捕获或重新抛出的子类。这些异常用于除非您正在处理错误代码或当您的 VM 主机着火时,否则不会发生的问题。

于 2011-09-19T13:26:08.080 回答
2

While this is not clearly documented within Jackson, rationale for IOExceptions is simple: IOExceptions from input sources (and output targets) are thrown as is -- since Jackson itself can not do anything for these, they are thrown as is. The only additional source for IOExceptions are things that are conceptually part of low-level (data-format independent) I/O handling, specifically, decoding of characters encodings like UTF-8.

From this, it seems relatively intuitive that JsonParsingException is for problems related to trying to parse invalid content; and JsonMappingException for problems at data-binding level. a

于 2011-09-20T16:42:45.020 回答
1

您应该IOException以与处理 json 异常并包装它的方式相同的方式进行处理。由于杰克逊的文档非常缺乏,你真的不知道为什么无论如何都会抛出它们(“未知错误”除外)。

于 2011-09-19T13:00:35.667 回答
0

在尝试/捕获/重新抛出样板代码中包装十几个方法时,耐心可能会变干。我发现龙目岛可以为我处理。希望它有帮助 https://projectlombok.org/features/SneakyThrows

于 2021-06-14T13:43:33.220 回答