I have a scenario which I am not sure how to google, so I’d open a question myself. If its a duplicate please link it here so I can give that question credit.
Anyway,
I have a Java Object with fields that I have the following annotations:
@JsonSerialize(using = CustomSerializer.class) @JSonDeserialize(using = CustomDeserializer.class) private Date systemDate;
The business dictates that certain systemDate values in different database have different time zones (not sure why they did not standardize to UTC).
Here is an example of my CustomSerializer.java:
@Override
public void serialize(Date, value, JsonGenerator gen, SerializerProvider arg2) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
if (value == null) {
gen.writeNull();
} else {
gen.writeString(formatter.formate(value.getTime()));
}
}
Instead of creating a new serializer class per timezone, is there a way to pass the timezone argument(s) to this class (and also my Deserializer class)?
Advertisement
Answer
You need to create a custom annotation as below:
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface DateSerialize {
String timeZone();
}
Now in the field systemDate add this new annotation by passing the timezone
@DateSerialize(timeZone = "UTC") @JsonSerialize(using = CustomSerializer.class) @JSonDeserialize(using = CustomDeserializer.class) private Date systemDate;
Your serializer class should implement ContextualSerializer this would allow us to get the BeanProperty from where we could get the annotation details.
public class DateSerializer extends JsonSerializer<Date> implements ContextualSerializer {
String timeZone;
public DateSerializer() {
this("UTC");
}
public DateSerializer(String tz) {
timeZone = tz;
}
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
if (value == null) {
gen.writeNull();
} else {
gen.writeString(formatter.format(value.getTime()));
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
DateSerialize annotation = property.getAnnotation(DateSerialize.class);
String tz = (annotation == null) ? "UTC" : annotation.timeZone();
return new DateSerializer(tz);
}
}
Similarly you could create a deserializer by implementing ContextualDeserializer.