I'm trying to write a custom deserializer for Jackson and I want to make it generic (generic in the sense of working on any type, not as in "generics").
However I cannot seem to figure out how to get a handle to the type of the field being deserialized.
Eg, I'm looking to do something like the following:
@Override
public MyObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Class c = <get type of current field>
// do something with that type
return new SubclassOfC(somedata based on c);
}
It's specifically the get type of current field part that I have struggled with.
Edit: It is the type of the java field I am interested in.
You don't -- deserializers are registered by type, so you need to construct deserializer to know what type it is expected to deserialize.
If you do want to registered a generic deserializer, you can however make things more dynamic by implementing ContextualDeserializer
. Its createContextual()
method is called with BeanProperty
argument, and you can check things like name of the property (which may be null, in case of root values which are not referenced by a property) and type (which is the declared type).
This method can then return a new instance (do NOT modify original deserializer, since it is shared by all properties), configured with all extra information you need.
I have solved my particular problem by adding an implementation of Deserializers to the ObjectMapper. Eg
Deserializers d = new Deserializers.Base() {
@Override
public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException {
if (property.getType().getContentType() != null)
return new EnumDeserializer(property.getType().getContentType().getRawClass());
return new EnumDeserializer(property.getType().getRawClass());
}
};
mapper.setDeserializerProvider(mapper.getDeserializerProvider().withAdditionalDeserializers(d));
This will return my custom EnumDeserializer instantiated for each separate Enum type.
I solved it like this.
Get current field java type...
@Override
public Enum deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException, JsonProcessingException {
System.out.println("EnumDeserializer ....");
Field field = findField(jsonparser.getCurrentName(), jsonparser.getCurrentValue().getClass());
Class<?> javaType = field.getType();
return null;
}
public Field findField(String name, Class<?> c) {
for (; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (field.getName().equals(name)) {
return field;
}
}
}
return null;
}
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