Jackson's ObjectMapper#readValue
成员抛出三个已检查的例外:
IOException JsonParseException JsonMappingException
JsonParseException
和JsonMappingException
延长IOException
。我想包装前面提到的两个子类并抛出我自己的自定义异常,然而,被检查的基类IOException
要求我捕获或抛出它。
将IOException
扔到调用层是没有意义的,但是,如果我把它隐藏起来,那就是一种气味。我最初的想法是不抓住它并将其留给调用者/运行时异常机制来处理它......但是,我不想强迫调用者捕获或指定。
在这种情况下,人们做了什么?
答案 0 :(得分:11)
简短回答:如果您处理IO,则需要处理IOException
。如果你不处理IO,那么IOException
应该变成未经检查的异常,因为它们是错误代码的症状。
更长的答案:
readValue
总是需要一个JsonParser
,它可以包含在IO(例如文件或URL)中。如果您正在处理IO,则无法处理IOException
s,您应该处理它们或以某种方式重新抛出/传递它们。在IO期间可能发生任何事情,您应该准备好处理异常。
但是,如果您确定JsonParser
实例不使用IO(例如,您使用JsonFactory#createJsonParser(java.lang.String)
在字符串上创建JSON解析器),您可以假设任何IOException
你收到的是你的代码或杰克逊的错误。通常,抛出未经检查的异常是处理它的正确方法:
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.");
}
Nota bene:我的Java生锈了,我从未使用过Jackson,所以请考虑上面的块是伪代码。
在任何情况下,您都不需要在AssertionError
中声明throws
,因为它们是未经检查的例外情况。作为java.lang.RuntimeException
或java.lang.Error
的子类的所有内容都不需要被明确捕获或重新抛出。这些异常用于预计不会发生的问题,除非您正在处理错误的代码或VM的主机发生故障。
答案 1 :(得分:1)
您应该像处理json异常一样处理IOException
并将其包装起来。由于杰克逊的文档缺乏这么多,你真的不知道为什么他们中的任何一个都被抛出(除了“一个未知的错误”)。
答案 2 :(得分:1)
虽然杰克逊没有明确记录这一点,但IOExceptions的基本原理很简单:输入源(和输出目标)的IOExceptions按原样抛出 - 因为杰克逊本身不能为这些做任何事情,所以它们按原样抛出。 IOExceptions的唯一额外来源是概念上属于低级(数据格式无关)I / O处理的东西,特别是UTF-8等字符编码的解码。
从这一点来看,JsonParsingException似乎与尝试解析无效内容相关的问题相对直观;和数据绑定级别的问题的JsonMappingException。 一个
答案 3 :(得分:0)
在 try/catch/rethrow 样板代码中包装十几种方法时,可能会失去耐心。我发现 Lombok 可以为我处理。 希望能帮助到你 https://projectlombok.org/features/SneakyThrows