jsonvalue - json annotation java
Jackson y esa temida IOException (3)
El miembro de ObjectMapper#readValue
Jackson arroja tres excepciones comprobadas:
IOException JsonParseException JsonMappingException
JsonParseException
y JsonMappingException
extienden IOException
. Quiero envolver las dos clases secundarias antes mencionadas y lanzar mis propias excepciones personalizadas; sin embargo, la clase base, IOException
, que se verifica, requiere que yo también la capture o lance.
No tiene sentido que arroje la IOException
a la capa de llamada, pero, adversamente, es un olor si la oculto. Mi idea original era no captarla y dejar que el mecanismo de excepción de llamadas / tiempos de ejecución se ocupara de ella ... sin embargo, no quiero forzar a la persona que llama a capturar o especificar.
¿Qué hace uno en tal situación?
Debe manejar la IOException
la misma manera que maneja las excepciones json y envolverla. Como la documentación de Jackson carece de tanto, no se sabe por qué se arrojan ninguno (salvo "un error desconocido").
Respuesta corta: si se ocupa de IO, se ocupa de IOException
s. Si no se ocupa de IO, entonces IOException
s se debe convertir en excepciones no verificadas, ya que son síntomas de código defectuoso.
Respuesta más larga:
readValue
siempre toma un JsonParser
, que puede estar envuelto alrededor de IO (por ejemplo, un archivo o una URL). Si está lidiando con IO, no hay forma de lidiar con IOException
, y debe manejarlos o volver a lanzarlos / pasarlos de alguna manera. Cualquier cosa puede suceder durante IO, y debe estar preparado para lidiar con las excepciones.
Sin embargo, si está seguro de que sus instancias JsonParser
no usan IO (por ejemplo, usó JsonFactory#createJsonParser(java.lang.String)
para crear un analizador JSON en una cadena), puede suponer que cualquier IOException
que reciba son errores , ya sea en tu código o en Jackson. Por lo general, lanzar una excepción sin marcar es la forma correcta de manejarlo:
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: mi Java está oxidada y nunca he usado Jackson, así que considera que el bloque anterior es un seudocódigo.
En cualquier caso, nunca es necesario declarar AssertionError
en throws
, porque son excepciones sin marcar. Todo lo que es una subclase de java.lang.RuntimeException
o java.lang.Error
no necesita ser capturado o rediseñado de forma explícita. Estas excepciones se usan para problemas que no se espera que ocurran a menos que se trate de un código defectuoso o cuando el host de su VM esté en llamas.
Si bien esto no está claramente documentado en Jackson, la justificación de IOExceptions es simple: IOExcepciones de las fuentes de entrada (y los objetivos de salida) se lanzan como están, ya que Jackson no puede hacer nada por esto, se lanzan como están. La única fuente adicional para IOExceptions son cosas que son conceptualmente parte del manejo de E / S de bajo nivel (formato de datos), específicamente, la decodificación de codificaciones de caracteres como UTF-8.
A partir de esto, parece relativamente intuitivo que JsonParsingException es para problemas relacionados con el intento de analizar el contenido no válido; y JsonMappingException para problemas en el nivel de enlace de datos. un