Use ISO-8601 dates in JAX-RS responses

 ̄綄美尐妖づ 提交于 2019-12-01 10:23:39

问题


I'm building RESTful web services using Java EE 7 on GlassFish 4. When serializing POJOs containing java.util.Date objects, the timezone information is not included.

How can I customize object serialization so java.util.Dates have timezone info included?

For example, instead of this:

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

I'd instead like this:

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

Where the server's timezone is GMT + 09:30.


回答1:


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

The workaround is to switch JSON providers to Jackson.

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

<!-- 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 a 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.
    }
}

The default behaviour of Jackson is to represent java.util.Date in its milliseconds since the epoch form. To change that 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();
}


来源:https://stackoverflow.com/questions/23730062/use-iso-8601-dates-in-jax-rs-responses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!