Use ISO-8601 dates in JAX-RS responses

前端 未结 1 1826
既然无缘
既然无缘 2021-01-15 18:05

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 inc

相关标签:
1条回答
  • 2021-01-15 18:52

    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();
    }
    
    0 讨论(0)
提交回复
热议问题