如何(联合国)将日期作为杰克逊的时间戳进行编组 [英] How do I (un)marshall a Date as a time-stamp with jackson

查看:103
本文介绍了如何(联合国)将日期作为杰克逊的时间戳进行编组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到麻烦(un)将java.util.Date对象编组到时间戳中。理想情况下,时间戳应采用UTC-0格式,而不是服务器的本地时区。虽然如果需要,我可以很容易地解决这个问题。

I'm having trouble (un)marshalling java.util.Date objects into timestamps. Ideally the timestamps should be in a UTC-0 format and not the server's local time zone. Although I can work around that pretty easily if I need to.

注意:我知道这里有几个关于堆栈溢出的类似主题但我遇到的每个人都要么过时(关于正在使用的API)或与将Date对象序列化为字符串有关。

NB: I am aware that here are several similar topics on stack overflow but everyone I have come across is either outdated (with respect to the API's being used) or are related to serializing Date objects to strings.

以下是我的POM文件的摘录:

Here is an excerpt of my POM file:

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.15</version>
</dependency>

示例模型类:

public class PersonJSON {
    private Date birthDate;
}

预期输出(假设出生日期是2015年2月1日00:00:00 UTC -0):

Expected output (assuming birth date is 01 Feb 2015 00:00:00 UTC-0):

{"birthDate":1422748800000}

当前输出:

{"birthDate":"2015-02-01"}

是否可以解决此问题(理想情况下使用注释)?

Is it possible to fix this (ideally using an annotation)?

解决方案

事实证明错误是由Java.sql的隐式转换引起的.Date to Java.util.Date。转换不会抛出任何异常,并且sql.Date扩展了util.Date,因此逻辑上它应该可以工作,但事实并非如此。解决方案是从Java.sql.Date中提取时间戳,并将其用作Java.util.Date构造函数的输入。

As it turns out the error was caused by an implicit conversion from Java.sql.Date to Java.util.Date. The conversion throws no exceptions and the sql.Date extends util.Date so logically it should work, but it doesn't. The solution was to extract the timestamp from the Java.sql.Date and use it as input to the Java.util.Date constructor.

如果您确实要更改假设你有一个有效的Java.util.Date对象,格式化peeskillet列出的方法是正确的。

If you do want to alter the format the approaches listed by peeskillet is correct assuming you have a valid Java.util.Date object.

推荐答案

你只需要配置 ObjectMapper 上的SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 。从我测试的我不需要配置反序列化,它通过时间戳工作得很好。

You just need to configure the SerializationFeature.WRITE_DATES_AS_TIMESTAMPS on the ObjectMapper. From what I tested I didn't need to configure the deserialization, it worked fine passing a timestamp.

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) { return mapper; }

}

至于每个字段的注释设置此功能,我不知道如何在没有编写自定义序列化程序的情况下与杰克逊这样做(但我不怀疑是否还有其他方法)。您始终可以使用Jackson提供程序附带的JAXB注释支持。只需写一个 XmlAdapter 并使用 @XmlJavaTypeAdatper(YourDateAdapter.class) 。这是示例

As far as setting this feature by annotation per field, I am not sure how to do that with Jackson, without writing a custom serializer (but I wouldn't doubt if there is some other way out there). You can always use the JAXB annotation support that comes with the Jackson provider. Just write an XmlAdapter and annotate the field with @XmlJavaTypeAdatper(YourDateAdapter.class). Here's an example

完整示例。

必需的依赖项

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.15</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.15</version>
</dependency>

测试(你需要从上面注册上下文解析器)

Test (you need to register the context resolver from above)

import java.util.Date;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import jersey.stackoverflow.provider.ObjectMapperContextResolver;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

public class ObjectMapperTest extends JerseyTest {

    public static class Person {
        public Date birthDate;
    }

    @Path("/person") @Produces(MediaType.APPLICATION_JSON)
    public static class PersonResource {
        @GET 
        public Response getPerson() {
            Person person = new Person();
            person.birthDate = new Date();
            return Response.ok(person).build();
        }
    }

    @Override
    public Application configure() {
        return new ResourceConfig(PersonResource.class,
                                  ObjectMapperContextResolver.class);
    }

    @Test
    public void test() {
        String personJson = target("person").request().get(String.class);
        System.out.println(personJson);
    }
}

结果: {birthDate :1423738762437}

我不认为这个答案是正确的。杰克逊似乎已默认将其序列化为时间戳。如果我们不想要时间戳,那么我们将上面的配置设置为 false 。但这仍然没有回答OP的问题。不确定是什么问题。

I don't think this answer is correct. It seems Jackson already serializes as timestamps by default. If we didn't want timestamps, then we would set the above configuration as false. But this still does not answer the OPs question. Not sure what the problem is.

这篇关于如何(联合国)将日期作为杰克逊的时间戳进行编组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆