我在GlassFish 4上使用Java EE 7构建RESTful Web服务。在序列化包含java.util.Date
个对象的POJO时,不包括时区信息。
如何自定义对象序列化,以便java.util.Date
包含时区信息?
例如,而不是:
{
"id": 1234,
"foo": "2014-05-19T13:53:49.392"
}
我反而喜欢这样:
{
"id": 1234,
"foo": "2014-05-19T13:53:49.392+09:30"
}
服务器的时区为GMT + 09:30。
答案 0 :(得分:6)
这是由MOXy中的bug引起的,它是GlassFish中JAX-RS的默认JSON(反)序列化器。
解决方法是将JSON提供程序切换到Jackson。
第一步是将这些依赖项添加到构建中:
<!-- 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>
下一步,添加JacksonFeature
作为提供程序,将MOXy替换为JSON序列化程序:
@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的默认行为是以纪元形式出现的毫秒数表示java.util.Date
。要将其更改为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();
}