After upgrading a Spring Boot upgrade from 1.3.3 to 1.4.0, I have noticed a change of behavior when serializing a org.joda.time.DateTime.
Let's build up a simple Spring boot + Maven Project.
The pom.xml dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
<dependencies>
The domain object:
@Document(collection="items")
@TypeAlias("item")
public class Item {
@Id
private String id;
private DateTime date;
/* getters/setters omitted */
}
The repository:
public interface ItemRepository extends MongoRepository<Item, String>{}
Now, if I GET any item resource, I get the following result:
{
"_embedded" : {
"items" : [ {
"id" : "57bf084a452105f14763cce7",
"date" : "1970-01-01T00:00:00.000Z",
"_links" : {
"self" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
},
"item" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
}
}
} ]
},
/* omitted links and meta data */
}
Which is fine.
Now, if i upgrade Spring Boot to 1.4.0.RELEASE, without touching anything else in my code base, I get the following:
{
"_embedded" : {
"items" : [ {
"id" : "57bf084a452105f14763cce7",
"date" : {
"content" : "1970-01-01T00:00:00.000Z"
},
"_links" : {
"self" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
},
"item" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
}
}
} ]
},
/* links and metadata omitted */
}
The datetime is now serialized as { "content" : "1970-01-01T00:00:00.000Z" } instead of "1970-01-01T00:00:00.000Z"
This problem is easily solved by annotating the DateTime field with @JsonFormat:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private DateTime date;
Actually, I don't like using @JsonFormat. Instead, I use a custom Jackson2ObjectMapperBuilder (it lets me handle my other serializers and deserializers, manually or via @JsonComponent...)
@Configuration
public class JacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializerByType(DateTime.class, new DateTimeSerializer());
return builder;
}
}
Bad news, I still get the same result. I've tried with a custom serializer, I still get the "content" key in the way. Only by using the com.fasterxml.jackson.databind.ser.std.ToStringSerializer instead of the com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer do I (almost) get what I want:
{
"_embedded" : {
"items" : [ {
"id" : "57bf084a452105f14763cce7",
"date" : "1970-01-01T01:00:00.000+01:00",
"_links" : {
"self" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
},
"item" : {
"href" : "http://localhost:8082/items/57bf084a452105f14763cce7"
}
}
} ]
},
/* links and metadata omitted */
}
In a nutshell, what's happening? Where does that extra "content" key come from and should it be there? I'd like to report this bug, but I don't know who is concerned, the developers from Spring Boot, or Jackson?