Reputation: 5598
I need to deserialize a JSON object, containing another JSON object (as a String) as a value. What is a best way to achieve this (whithout instantiating an object mapper inside getter for deserialisation of inner class object which takes 50 to 100ms on Android devices). I'm using Jackson Annotations, so annotating to achieve what i want is preferred.
upd. I'm expecting some annotation based solution. Something like
@JsonDeserialize(String as MyCustomObject)
which would be equal to
MyCustomObject myCustomObject = mapper.readValue(string, MyCustomObject.class)
Upvotes: 2
Views: 342
Reputation: 10853
I don't think there an annotation which will tell Jackson to treat the input string as a raw JSON and construct an object out of it. I'd probably use a custom deserializer injecting a shard object mapper.
Here is an example:
public class JacksonInjectObjectMapper {
private static final String JSON =
"{\"field1\":\"{\\\"field0\\\":\\\"value0\\\"}\", " +
"\"field2\":\"value2\"}";
public static class Foo {
public String field0;
@Override
public String toString() {
return "Foo{" +
"field0='" + field0 + '\'' +
'}';
}
}
public static class Bean {
@JsonDeserialize(using = FooDeserializer.class)
public Foo field1;
public String field2;
@Override
public String toString() {
return "Bean{" +
"field1=" + field1 +
", field2='" + field2 + '\'' +
'}';
}
}
public static class FooDeserializer extends JsonDeserializer<Foo> {
@Override
public Foo deserialize(
final JsonParser jp, final DeserializationContext ctxt)
throws IOException {
final ObjectMapper mapper = (ObjectMapper) ctxt.findInjectableValue(
ObjectMapper.class.getName(),
null,
null);
final String json = jp.getValueAsString();
System.out.println(json);
return mapper.readValue(json, Foo.class);
}
}
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
final InjectableValues.Std injectableValues = new InjectableValues.Std();
injectableValues.addValue(ObjectMapper.class, mapper);
mapper.setInjectableValues(injectableValues);
final Bean bean = mapper.readValue(JSON, Bean.class);
System.out.println(bean);
}
}
Output:
{"field0":"value0"}
Bean{field1=Foo{field0='value0'}, field2='value
Upvotes: 1