【问题标题】:Serialize Date in a JSON REST web service as ISO-8601 string将 JSON REST Web 服务中的日期序列化为 ISO-8601 字符串
【发布时间】:2012-11-28 00:15:02
【问题描述】:

我有一个使用 JBoss AS 7.1 的 JAX-RS 应用程序,并且我发布/获取 JSON 和 XML 对象,其中包括日期 (java.util.Date):

@XmlRootElement
@XmlAccessorType(XmlAccessField.FIELD)
public class MyObject implements Serializable
{
    @XmlSchemaType(name = "dateTime")
    private Date date;
    ...
}

当我在 get 方法上使用 @Produce("application/xml") 时,对象被序列化为 XML 并且日期被转换为 ISO-8601 字符串(例如“2012-12-10T14:50:12.123+02 :00")。

但是,如果我在 get 方法上使用 @Produce("application/json"),则 JSON 对象中的日期是时间戳(例如“1355147452530”)而不是 ISO-8601 字符串。

如何配置 JAX-RS 实现 (RESTEasy) 以将 JSON 格式的日期序列化为 ISO-8601 字符串而不是时间戳?

感谢您的回答。

注意:我还尝试使用自定义 JAX-RS 提供程序对日期进行 JSON 序列化

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomJsonDateProvider implements MessageBodyWriter<Date>
{
    ...
}

这个提供者似乎是在 JBoss 启动时由 RESTeasy 注册的:

[org.jboss.jaxrs] Adding JAX-RS provider classes: package.CustomJsonDateProvider
...
[org.jboss.resteasy.cdi.CdiInjectorFactory] No CDI beans found for class package.CustomJsonDateProvider. Using default ConstructorInjector.

但它从未使用过!

【问题讨论】:

    标签: json jax-rs jboss7.x resteasy


    【解决方案1】:

    我假设你的 json 解析器是 Jackson,试试:

    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
    public Date date;
    

    (自杰克逊 2.0 起)

    【讨论】:

    • 直到我在@JsonFormat 注释之前添加了@JsonSerialize(as = Date.class),这对我不起作用。
    【解决方案2】:

    默认的 JBoss 解析器是 Jettison,但我无法更改日期格式。所以我切换到 Jackson 并在我的项目中添加了以下类来配置它:

    @Provider
    @Produces(MediaType.APPLICATION_JSON)
    public class JacksonConfig implements ContextResolver<ObjectMapper>
    {
        private final ObjectMapper objectMapper;
    
        public JacksonConfig()
        {
            objectMapper = new ObjectMapper();
            objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESPAMPS, false);
        }
    
        @Override
        public ObjectMapper getContext(Class<?> objectType)
        {
            return objectMapper;
        }
    }
    

    【讨论】:

    • 我的 JBoss EAP 7 JAX-RS 实现是 RESTEasy,我不想添加 Jackson 依赖项。经过一天的研究,我最终得到了您的解决方案 (JacksonConfig)。我添加了 Maven 依赖 &lt;dependency&gt;&lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;&lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;&lt;version&gt;2.8.7&lt;/version&gt;&lt;/dependency&gt; 并使用了自定义日期格式 objectMapper.setDateFormat(new SimpleDateFormat("dd.MM.yyyy")) 而不是默认设置的 objectMapper.configure()
    【解决方案3】:

    抱歉人们大声喊叫 - 我在这里找到了答案

    http://wiki.fasterxml.com/JacksonFAQDateHandling,

    这里

    http://wiki.fasterxml.com/JacksonFAQ#Serializing_Dates,

    这里

    http://wiki.fasterxml.com/JacksonHowToCustomSerializers

    这里

    http://jackson.codehaus.org/1.1.2/javadoc/org/codehaus/jackson/map/util/StdDateFormat.html

    使用@JsonSerialize(using= ... ) 方式:

    public class JsonStdDateSerializer
    extends JsonSerializer<Date> {
    
      private static final DateFormat iso8601Format =
        StdDateFormat.getBlueprintISO8601Format();
    
      @Override
      public void serialize(
        Date date, JsonGenerator jgen, SerializerProvider provider)
      throws IOException, JsonProcessingException {
    
        // clone because DateFormat is not thread-safe
        DateFormat myformat = (DateFormat) iso8601Format.clone();
        String formattedDate = myformat.format(date);
        jgen.writeString(formattedDate);
      }
    }
    

    【讨论】:

      【解决方案4】:

      声明与 Soap/XML 相同的 Serializer

      @XmlElement(name = "prealert_date")
      @XmlSchemaType(name = "dateTime")
      @JsonSerialize(using = XMLGregorianCalendarSerializer.class)
      protected XMLGregorianCalendar prealertDate;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        • 2019-02-27
        • 1970-01-01
        • 2017-07-25
        • 2016-01-06
        相关资源
        最近更新 更多