Reputation: 1296
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?
Upvotes: 5
Views: 6093
Reputation: 566
According to previous solution I create my custom date deserializer.And it works for me.
First create your annotaition.
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomDateFormat {
String customDateFormat();
}
Second create your serializer class.
public class CustomDateDeserializer extends StdDeserializer<DateTime> implements ContextualDeserializer {
private SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
private String customDateFormat = null;
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
public CustomDateDeserializer(Class<?> vc, String customDateFormat) {
super(vc);
this.customDateFormat = customDateFormat;
}
@Override
public DateTime deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String date = jsonparser.getText();
try {
if (!Util.nullToBosluk(date).equals(""))
return new DateTime(getDateFormat(this.customDateFormat).parse(date));
} catch (ParseException e) {
throw new RuntimeException(e);
}
return null;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
CustomDateFormat customDateFormatAnn = property.getAnnotation(CustomDateFormat.class);
if (customDateFormatAnn != null) {
String customParam = customDateFormatAnn.customDateFormat();
return new CustomDateDeserializer(this._valueClass, customParam);
}
return this;
}
private DateFormat getDateFormat(String customDateFormat) {
if (StringUtils.isNotBlank(customDateFormat))
return new SimpleDateFormat(customDateFormat);
else
return this.formatter;
}
}
Finally use your new annotation in your code.
...
@JsonDeserialize(using = CustomDateDeserializer.class)
DateTime invoiceDate;
@JsonDeserialize(using = CustomDateDeserializer.class)
@CustomDateFormat(customDateFormat = "dd/MM/yyyy HH:mm")
DateTime createDate;
...
Upvotes: 1
Reputation: 10127
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 ...;
}
}
Upvotes: 8