Jackson custom date serializer

jackson, java, json, serialization

Solution

If you cannot use @JsonFormat from Jackson 2, I'd recommend you to introduce your own custom annotation which will contain the format field. Your serailizer should then implement the `ContextualSerializer` interface to get access to the annotation value.

Here is 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 the `ObjectMapper` you can register your custom serializer for all the `Date` types, so you want longer need to put `@JsonSerialize` annotation.

Here is an example:

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

Problem

I need to set format for class' date serialization. I have the version of Jackson, which doesn't have @JsonFormat. That's Why I wrote 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 another fields which have different date's formats and I don't want to create another classes for serialization. Can I add all needed formats like constants to CDJsonDateSerializer class and set needed format with annotation `@JsonSerialize` ? Something like this: `@JsonSerialize(using = CDJsonDateSerializer.class, CDJsonDateSerializer.FIRST_FORMAT)`. AFTER THE ANSWER BELOW: It works after some corrections. I've changed the way of getting annotation in createContextual method: ``` @Override public JsonSerializer createContextual(SerializationConfig serializationConfig, BeanProperty beanProperty) { return new CustomDateSerializer(beanProperty.getAnnotation(JsonDateFormat.class).value()); } ``` And I've added @JacksonAnnotation to my created new annotation JsonDateFormat: ``` @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JsonDateFormat { String value(); } ```

Original source

Related problems