edge66
edge66

Reputation: 161

spring boot Joda DateTime Serialisation

I'm trying to serialize Joda DateTime properties as ISO-8601 using Spring Boot v1.2.0.BUILD-SNAPSHOT Here is my very simple REST Application.

@RestController
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    class Info{

       private DateTime dateTime;

        public Info(){
            dateTime = new DateTime();
        }
        public DateTime getDateTime() {
           return dateTime;
        }

        public void setDateTime(DateTime dateTime) {
           this.dateTime = dateTime;
        }
    }

    @RequestMapping("/info")
    Info info() {
        return new Info();
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
   public Module getModule(){
        return new JodaModule();
   }
}

The dateTime is being serialized as a timestamp e.g. {"dateTime":1415954873412} I've tried adding

@Bean
@Primary
public ObjectMapper getObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                false);
    return objectMapper;
}

but that didn't help either. So how do I configure Jackson in Spring Boot to serialize using the ISO-8601 format? BTW: I only added the following dependencies to my Gradle build

compile("joda-time:joda-time:2.4")
compile("org.jadira.usertype:usertype.jodatime:2.0.1")
compile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.4.2");

Upvotes: 16

Views: 25944

Answers (5)

raspacorp
raspacorp

Reputation: 5307

There is also a joda-date-time-format property (I think this property appeared for the first time in Spring boot 1.3.x versions) that you can set in your application.properties which will work for jackson serialization/deserialization:

From: https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

spring.jackson.joda-date-time-format= # Joda date time format string. If not configured, "date-format" will be used as a fallback if it is configured with a format string.

So if you want to use the ISO format you can set it like this:

spring.jackson.joda-date-time-format=yyyy-MM-dd'T'HH:mm:ss.SSSZ

You can have different number of 'Z' which changes the way the time zone id or offset hours are shown, from the joda time documentation (http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html):

Zone: 'Z' outputs offset without a colon, 'ZZ' outputs the offset with a colon, 'ZZZ' or more outputs the zone id.

Upvotes: 0

Tyler
Tyler

Reputation: 484

Add this to your application.* in your resources. (I use yamel so it's .yml for me, but should be .properties by default)

spring.jackson.date-format: yyyy-MM-dd'T'HH:mm:ssZ

Or whatever format you want.

Upvotes: 4

tadaskay
tadaskay

Reputation: 111

With Spring Boot 1.2 you can use a fluent builder for building ObjectMapper instance:

@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder
              .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
              .build();
}

As for JodaModule, it will be autoconfigured when com.fasterxml.jackson.datatype:jackson-datatype-joda is on classpath.

Upvotes: 8

Phil Webb
Phil Webb

Reputation: 8622

Since you're using Spring Boot 1.2 you should be able to simply add the following to your application.properties file:

spring.jackson.serialization.write_dates_as_timestamps=false

This will give output in the form:

{
    "dateTime": "2014-11-18T19:01:38.352Z"
}

If you need a custom format you can configure the JodaModule directly, for example to drop the time part:

@Bean
public JodaModule jacksonJodaModule() {
    JodaModule module = new JodaModule();
    DateTimeFormatterFactory formatterFactory = new DateTimeFormatterFactory();
    formatterFactory.setIso(ISO.DATE);
    module.addSerializer(DateTime.class, new DateTimeSerializer(
        new JacksonJodaFormat(formatterFactory.createDateTimeFormatter()
            .withZoneUTC())));
    return module;
}

Upvotes: 20

tom
tom

Reputation: 2712

Pass a new JodaModule() to the constructor of your object mapper.

Annotate your Info methods with the ISO pattern

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")

or I think you can use this if you're using spring

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateTimeFormat.ISO.DATE_TIME)

Upvotes: 4

Related Questions