Use ISO-8601 dates in JAX-RS responses

I am creating RESTful web services using Java EE 7 on GlassFish 4. When serializing POJOs containing java.util.Date objects, time zone information is not included.

How to set up serialization of objects, so java.util.Date contains time zone information?

For example, instead:

 { "id": 1234, "foo": "2014-05-19T13:53:49.392" } 

I would like it:

 { "id": 1234, "foo": "2014-05-19T13:53:49.392+09:30" } 

If the server’s time zone is GMT + 09:30.

+1
java json jax-rs glassfish iso8601
source share
1 answer

This is caused by a bug in MOXy, which by default is the JSON (de) serializer for JAX-RS in GlassFish.

The workaround is to switch the JSON providers to Jackson.

The first step is to add these dependencies to the assembly:

 <!-- Provides JacksonFeature --> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.8</version> <scope>provided</scope> </dependency> <!-- Provides ObjectMapper and SerializationConfig --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> <type>jar</type> </dependency> 

Next step, add JacksonFeature as the provider, which will replace MOXy as the JSON serializer:

 @ApplicationPath("/api/1") public class ApplicationConfig extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> resources = new java.util.HashSet<>(); addRestResourceClasses(resources); // Add Jackson feature. resources.add(org.glassfish.jersey.jackson.JacksonFeature.class); return resources; } private void addRestResourceClasses(Set<Class<?>> resources) { // JAX-RS resource classes added here - maintained by NetBeans. } } 

Jackson's default behavior is to represent java.util.Date in milliseconds since the creation of the era. To change this to ISO-8601:

 import java.text.SimpleDateFormat; import java.util.TimeZone; import javax.ws.rs.Produces; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; @Provider @Produces("application/json") public class JacksonConfigurator implements ContextResolver<ObjectMapper> { public JacksonConfigurator() { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); mapper.setDateFormat(dateFormat); mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); } @Override public ObjectMapper getContext(Class<?> clazz) { return mapper; } private final ObjectMapper mapper = new ObjectMapper(); } 
+5
source share

All Articles