Custom Date Serializer in Jackson

I need to set a format for serializing a class date. I have a Jackson version that does not have @JsonFormat. This is why I wrote a custom class:

public class CDJsonDateSerializer extends JsonSerializer<Date>{

@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    String dateString = dateFormat.format(date);
    jsonGenerator.writeString(dateString);
}

      

}

And used it:

@JsonSerialize(using = CDJsonDateSerializer.class)
private Date startDate;

      

But I have other fields that have different date formats and I don't want to create other classes to serialize. Can I add all the required formats such as constants to the CDJsonDateSerializer class and set the required format with annotation @JsonSerialize

? Something like that:

@JsonSerialize(using = CDJsonDateSerializer.class, CDJsonDateSerializer.FIRST_FORMAT)

...

AFTER ANSWER BELOW:

It works after some fixes. I changed the way I get annotation in createContextual :

@Override
public JsonSerializer createContextual(SerializationConfig serializationConfig, BeanProperty beanProperty) {
    return new CustomDateSerializer(beanProperty.getAnnotation(JsonDateFormat.class).value());
}

      

And I added @JacksonAnnotation to my newly created JsonDateFormat annotation:

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonDateFormat {
   String value();
}

      

+3


source to share


1 answer


If you cannot use @JsonFormat from Jackson 2, then I would recommend that you provide your own annotation that will contain the format field. Then your serailizer must implement the interface ContextualSerializer

to access the annotation value.

Here's an example for Jackson 1.9.X:

public class JacksonDateFormat {
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface MyJsonFormat {
        String value();
    }

    public static class Bean {
        @MyJsonFormat("dd.MM.yyyy") @JsonSerialize(using = MyDateSerializer.class)
        public final Date date1;

        @MyJsonFormat("yyyy-MM-dd") @JsonSerialize(using = MyDateSerializer.class)
        public final Date date2;

        public Bean(final Date date1, final Date date2) {
            this.date1 = date1;
            this.date2 = date2;
        }
    }

    public static class MyDateSerializer extends JsonSerializer<Date>
            implements ContextualSerializer {
        private final String format;

        private MyDateSerializer(final String format) {this.format = format;}

        public MyDateSerializer() {this.format = null;}

        @Override
        public void serialize(
                final Date value, final JsonGenerator jgen, final SerializerProvider provider)
                throws IOException {
            jgen.writeString(new SimpleDateFormat(format).format(value));
        }

        @Override
        public JsonSerializer createContextual(
                final SerializationConfig serializationConfig, final BeanProperty beanProperty)
                throws JsonMappingException {
            final AnnotatedElement annotated = beanProperty.getMember().getAnnotated();
            return new MyDateSerializer(annotated.getAnnotation(MyJsonFormat.class).value());
        }
    }

    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        final Bean value = new Bean(new Date(), new Date());
        System.out.println(mapper
                        .writerWithDefaultPrettyPrinter()
                        .writeValueAsString(value));
    }
}

      

Output:



{
  "date1" : "02.12.2014",
  "date2" : "2014-12-02"
}

      

If you have access to ObjectMapper

, you can register your own serializer for all types Date

, so you need more time to add annotation @JsonSerialize

.

Here's an example:

final ObjectMapper mapper = new ObjectMapper();
final SimpleModule module = new SimpleModule("", Version.unknownVersion());
module.addSerializer(Date.class, new MyDateSerializer(null));
mapper.registerModule(module);

      

+6


source







All Articles