I would like to know if it is possible to customize the deserialization of json depending the field name, for example
{
id: "abc123",
field1: {...}
other: {
field1: {....}
}
}
I the previous json, I would like to have a custom deserializer for the fields named "field1", in any level in the json.
The reason: We have our data persisted as JSON, and we have a REST service that returns such data, but before return it, the service must inject extra information in the "field1" attribute.
The types are very dynamic, so we cannot define a Java class to map the json to use annotations.
An first approach was to deserialize to Map.class and then use JsonPath to search the $..field1 pattern, but this process is expensive for bigger objects.
I appreciate any help.
Thanks,
Edwin Miguel
You should consider registering a custom deserializer with the ObjectMapper
for this purpose.
Then you should be able to simply map your JSON stream to a Map<String, Object>
knowing that your field1
objects will be handled by your custom code.
I create a custom deserializer and added it to a SimpleModule for the ObjectMapper
public class CustomDeserializer extends StdDeserializer<Map> {
public CustomDeserializer() {
super(Map.class);
}
@Override
public Map deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Map<String, Object> result = new HashMap<String, Object>();
jp.nextToken();
while (!JsonToken.END_OBJECT.equals(jp.getCurrentToken())) {
String key = jp.getText();
jp.nextToken();
if ("field1".equals(key)) {
MyObject fiedlObj= jp.readValueAs(MyObject.class);
//inject extra info
//...
result.put(key, fieldObj);
} else {
if (JsonToken.START_OBJECT.equals(jp.getCurrentToken())) {
result.put(key, deserialize(jp, ctxt));
} else if (JsonToken.START_ARRAY.equals(jp.getCurrentToken())) {
jp.nextToken();
List<Object> linkedList = new LinkedList<Object>();
while (!JsonToken.END_ARRAY.equals(jp.getCurrentToken())) {
linkedList.add(deserialize(jp, ctxt));
jp.nextToken();
}
result.put(key, linkedList);
} else {
result.put(key, jp.readValueAs(Object.class));
}
}
jp.nextToken();
}
return result;
}
}
The problem is that I had to implement the parsing for the remaining attributes.
For now, it is my solution...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With