Tengo el siguiente JSON:
{ "some_key": "{\"a\": 1, \"b\": \"text\"}" } Como puede ver, el campo some_key no es un objeto JSON, es una cadena que contiene JSON válido.
Me gustaría analizarlo en la siguiente estructura:
class Foo { Bar some_key; } class Bar { int a; String b; }ACTUALIZAR:
clase A y B, tiene getters y setters, constructores. No los he mostrado para mantener la muestra breve y simple.
No puedo editar la extraña estructura del JSON.
La pregunta es cómo pedirle a Jackson que analice el campo de cadena interno como un objeto JSON.
@t_liang está muy cerca, solo necesita un poco más de espacio que un comentario para mostrar el ejemplo de trabajo...
Con:
class Foo { @JsonDeserialize(using = BarDeserializer.class) private Bar some_key; } Entonces el ObjectMapper actual es en realidad el JsonParser.getCodec() :
public class BarDeserializer extends JsonDeserializer<Bar> { @Override public Bar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { String text = p.getText(); ObjectMapper mapper = (ObjectMapper) p.getCodec(); return mapper.readValue(text, Bar.class); } }Luego esto...
ObjectMapper mapper = new ObjectMapper(); Foo foo = mapper.readValue( "{ \"some_key\": \"{\\\"a\\\": 1, \\\"b\\\": \\\"text\\\"}\" }", Foo.class); System.out.println(foo.getSome_key());... muestra el valor esperado:
Bar [a=1, b=text]step 1: public class BarDeserializer extends JsonDeserializer<Bar> { @Override public Bar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { String text = p.getText(); return <your ObjectMapper>.readValue(text, Bar.class); } } step 2: class Foo { @JsonDeserialize(using=BarDeserializer.class) Bar some_key; } or @JsonDeserialize(using=BarDeserializer.class) class Bar { int a; String b; }Hay un par de problemas:
json proporcionado en el ejemplo no corresponde al esquema. Por ejemplo, según json , some_key es un campo de cadena (está entre comillas dobles), mientras que según el esquema, es un campo Boo . Debe cambiar json para que se parezca a lo siguiente (o cambiar some_value a tipo String):
{ "some_key": {\"a\": 1, \"b\": \"text\"} }
No hay getters o setters. Jackson no puede deserializar, no puede acceder a getters/setters a través de la reflexión.
Aquí está el ejemplo de trabajo:
class Foo { Bar some_key; public Bar getSome_key() { return some_key; } public void setSome_key(Bar some_key) { this.some_key = some_key; } } class Bar { int a; String b; public int getA() { return a; } public void setA(int a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } }Deserialización:
ObjectMapper mapper = new ObjectMapper(); Foo response = mapper.readValue("{\"some_key\": {\"a\": 1, \"b\": \"text\"}}", Foo.class);