【问题标题】:Use ISO-8601 dates in JAX-RS responses在 JAX-RS 响应中使用 ISO-8601 日期
【发布时间】:2014-07-06 23:02:04
【问题描述】:

我正在 GlassFish 4 上使用 Java EE 7 构建 RESTful Web 服务。在序列化包含 java.util.Date 对象的 POJO 时,不包括时区信息。

如何自定义对象序列化,以便 java.util.Dates 包含时区信息?

例如,而不是这个:

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

我更喜欢这样:

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

服务器的时区是 GMT + 09:30。

【问题讨论】:

  • 如果你使用 Jackson,你可以使用 ObjectMapper.setDateFormat
  • 是的,我刚才切换到 Jackson,它在响应中起作用,但现在在请求正文上解析失败。
  • 根据文档,这应该适用于序列化和反序列化。您也可以尝试使用自定义 DeserializerSerializer
  • 是的,问题似乎是无法解析的日期异常。显然yyyy-MM-dd'T'HH:mm:ss.SSSZ 无法解析2014-05-20T09:00:00.000+09:30。无论如何,如果我在其他人之前提出整个解决方案,我会将其作为答案发布。
  • 我认为您所在时区的冒号是问题所在。请看SimpleDateFormat

标签: java json glassfish jax-rs iso8601


【解决方案1】:

这是由 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();
}

【讨论】:

  • 效果很好,除了格式上有错字。 Z应该是'Z'。格式为:“yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 2013-02-03
  • 2022-10-20
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多