¿Cómo analizar valores sin procesar de elementos de matriz JSON con Jackson?
Al utilizar la deserialización de Jackson, sería genial tener una opción para deserializar un JSON array de elementos (de cualquier tipo: objeto, número, cadena) a un array de Java de String.
Veo que @JsonRawValue
permite tener una funcionalidad similar para los campos anidados. ¿Es posible implementar lo mismo para objetos de “nivel superior”?
void test(){
var payload = """ [
{"a": 1, "b": "hello"},
{"a": 2, "b": "bye"},
"something"
]
""";
// ¿Qué más se requiere para conseguir el efecto de @JsonRawValue?
String[] rawItems = new ObjectMapper().readValue(payload, String[].class);
assertEquals("""{"a": 1, "b": "hello"}""", rawItems[0]);
assertEquals("""{"a": 2, "b": "bye"}""", rawItems[1]);
assertEquals("\"something\"", rawItems[2]);
}
davy.ai
Para deserializar una matriz JSON de elementos a una matriz de cadenas Java, podemos usar la anotación
@JsonRawValue
. Sin embargo, esta anotación solo se aplica a campos anidados y no al objeto de nivel superior. Para implementar la misma funcionalidad para los objetos de nivel superior, necesitamos hacer uso de un JsonDeserializer personalizado.El deserializador personalizado debe registrarse con la instancia de
ObjectMapper
que usamos para deserializar la cadena JSON. Podemos hacer esto llamando al métodoregisterModule
en la instancia deObjectMapper
con una nueva instancia de la claseSimpleModule
. Luego, anulamos el métododeserialize
de la claseJsonDeserializer
para devolver una matriz de cadenas.Aquí hay un ejemplo de código que muestra cómo implementar esto:
En este ejemplo de código, definimos una clase
StringArrayDeserializer
que extiende la claseJsonDeserializer
. Anulamos el métododeserialize
para leer cada elemento en la matriz JSON y agregarlo a una lista de cadenas. Distinguimos entre objetos y valores verificando el tipo de token actual y usamos el métodoreadValueAsTree
para obtener la representación de cadena cruda de objetos.Luego registramos este deserializador personalizado con una instancia de
ObjectMapper
, y lo usamos para deserializar la cadena JSON en una matriz de cadenas. Verificamos que la deserialización funcione como se esperaba imprimiendo cada elemento en la matriz resultante.</string[]>