Reputation: 7137
I am having problems consistently serializing and deserializing a Joda DateTime from java to json and back again using Spring Boot and Jackson-databind 2.5.2. My pom.xml looks like this.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
When I serialize the DateTime object I get an integer representing the DateTime. Not what I expected actually, but fine. BUT when I go to save my object back I get the following error...
Failed to convert property value of type 'java.lang.String' to required type 'org.joda.time.DateTime' for property 'endTime';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type org.joda.time.DateTime for value '1428600998511'
For some reason it is serializing it to an integer but then deserializing it as if it's a string, which it is not. I also tried setting the endTime = new Date(intValue) before calling the rest service and that also failed trying to convert a string like 'Tue Apr 28 2015 00:00:00 GMT-0700 (PDT)' to a DateTime.
What am I doing wrong?
UPDATE:
Here is the JSON that I GET and that I try to immediately POST right back.
{
id: 4,
username: "",
name: "eau",
email: "aoue",
verbatimLocation: null,
latitude: null,
longitude: null,
startTime:null,
endTime: 1429034332312,
description: "ueoa",
media: [ ],
timeSubmitted: 1428600998000,
status: null,
submissionid: null
}
Upvotes: 7
Views: 10650
Reputation: 9490
For a more re-usable mechanism, you can create a JsonSerializer
:
/**
* When passing JSON around, it's good to use a standard text representation of
* the date, rather than the full details of a Joda DateTime object. Therefore,
* this will serialize the value to the ISO-8601 standard:
* <pre>yyyy-MM-dd'T'HH:mm:ss.SSSZ</pre>
* This can then be parsed by a JavaScript library such as moment.js.
*/
public class JsonJodaDateTimeSerializer extends JsonSerializer<DateTime> {
private static DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
@Override
public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.print(value));
}
}
Then you can annotate your get
methods with:
@JsonSerialize(using = JsonJodaDateTimeSerializer.class)
This gives you consistent formatting throughout your application, without repeating text patterns everywhere. It's also timezone aware.
Upvotes: 9
Reputation: 7137
In the end I was able to do as beerbajay said and use ...
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSSZ")
... to serialize my date. I did, though, end up going back to using a Long instead of a DateTime because dealing with the date on the javascript side was too troublesome. Finding a pattern that worked for jquery datepicker, joda DateTime, and for postgresql proved to be too much work for the little time I had.
Upvotes: 4