Skip to content
Advertisement

Adding custom arguments to Jackson deserializer

I have a custom deserializer. But I want to be able to pass additional arguments. For example

@JsonDeserialize(using=CustomDeserializer.class, customParm=value)
MyObject obj;

How can I pass in my custom parameter on the annotation?

Advertisement

Answer

You cannot add your own parameters to @JsonDeserialize, because you can’t alter Jackson’s implementation of this annotation.

However, you can achieve your goal in a slightly different way. You can invent your own annotation (let’s call it @MyAnnotation) and use that alongside with the @JsonDeserialize annotation on your property:

@JsonDeserialize(using = CustomDeserializer.class)
@MyAnnotation(customParm = "value")
private MyObject obj;

The implementation of the annotation is pretty straight-forward. The following example annotation just defines a single String parameter.

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String customParm();
}

Then you can access the parameters of @MyAnnotation from within your deserializer as follows.

  • As usual your deserializer needs to implement the deserialize method where you do the actual deserialization of the property.

  • Besides that your deserializer needs to implement the ContextualDeserializer interface and implement the createContextual method. Here you configure your deserializer (by getting the customParm from @MyAnnotation). Jackson will call this method before the actual deserialization.

public class CustomDeserializer extends StdDeserializer<MyObject> implements ContextualDeserializer {

    private String customParm = null;

    public CustomDeserializer() {
        super(MyObject.class);
    }

    public CustomDeserializer(String customParm) {
        super(MyObject.class);
        this.customParm = customParm;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
            throws JsonMappingException {
        MyAnnotation myAnnotation = property.getAnnotation(MyAnnotation.class);
        if (myAnnotation != null) {
            String customParm = myAnnotation.customParm();
            // return a new instance, so that different properties will not share the same deserializer instance
            return new CustomDeserializer(customParm);
        }
        return this;
    }

    @Override
    public MyObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // do your deserialization (using customParm)
        return ...;
    }
}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement