property jsonvalue jsonproperty ignorable annotation java json exception jackson convention

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