I have a JAX-RS application using JBoss AS 7.1, and I POST/GET JSON and XML objects which include Dates (java.util.Date):
@XmlRootElement
@XmlAccessorType(XmlAccessField.FIELD)
public class MyObject implements Serializable
{
@XmlSchemaType(name = "dateTime")
private Date date;
...
}
When I use @Produce("application/xml") on the get method, the objets are serialized as XML and the dates are converted into ISO-8601 strings (e.g. "2012-12-10T14:50:12.123+02:00").
However, if I use @Produce("application/json") on the get method, the dates in the JSON objects are timestamps (e.g. "1355147452530") instead of ISO-8601 strings.
How can I do to configure the JAX-RS implementation (RESTEasy) to serialize dates in JSON format as ISO-8601 strings instead of timestamps ?
Thank you for your answers.
Note: I also tried to use a custom JAX-RS provider to do the JSON serialization for Dates
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomJsonDateProvider implements MessageBodyWriter<Date>
{
...
}
This provider seems to be registered by RESTeasy on JBoss startup:
[org.jboss.jaxrs] Adding JAX-RS provider classes: package.CustomJsonDateProvider
...
[org.jboss.resteasy.cdi.CdiInjectorFactory] No CDI beans found for class package.CustomJsonDateProvider. Using default ConstructorInjector.
but it is never used !
I assume your json parser is Jackson, try:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
public Date date;
(since Jackson 2.0)
The default JBoss parser is Jettison, but I wasn't able to change the date format. So I switched to Jackson and added the following class to my project to configure it:
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper>
{
private final ObjectMapper objectMapper;
public JacksonConfig()
{
objectMapper = new ObjectMapper();
objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESPAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> objectType)
{
return objectMapper;
}
}
Sorry people for yelling out loud - I found the answers here
http://wiki.fasterxml.com/JacksonFAQDateHandling,
here
http://wiki.fasterxml.com/JacksonFAQ#Serializing_Dates,
here
http://wiki.fasterxml.com/JacksonHowToCustomSerializers
here
http://jackson.codehaus.org/1.1.2/javadoc/org/codehaus/jackson/map/util/StdDateFormat.html
Using the @JsonSerialize(using= ... ) way:
public class JsonStdDateSerializer
extends JsonSerializer<Date> {
private static final DateFormat iso8601Format =
StdDateFormat.getBlueprintISO8601Format();
@Override
public void serialize(
Date date, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
// clone because DateFormat is not thread-safe
DateFormat myformat = (DateFormat) iso8601Format.clone();
String formattedDate = myformat.format(date);
jgen.writeString(formattedDate);
}
}
Declare the same Serializer
used by Soap/XML:
@XmlElement(name = "prealert_date")
@XmlSchemaType(name = "dateTime")
@JsonSerialize(using = XMLGregorianCalendarSerializer.class)
protected XMLGregorianCalendar prealertDate;