Jersey 解析 Java 8 日期时间

Jersey parsing Java 8 date time(Jersey 解析 Java 8 日期时间)

本文介绍了Jersey 解析 Java 8 日期时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的用户类,我将符合 ISO 标准的日期时间保存在我的数据库中.

This is my user class, and I to save ISO compliant date time in my database.

public class User  {

    @Id
    private String id;

    private String email;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime loginDate;

 }

这是我的泽西控制器:

@POST
@Consumes("application/json")
@Produces("application/json")

public Response create(  User user) {

    Map<Object, Object> apiResponse = new HashMap<Object, Object>();
    Map<Object, Object> response  = new HashMap<Object, Object>();


    user = (User) userService.create(user);

}

我怎样才能在球衣中使用像这样的日期时间格式?是否可以发送数据时间 String 并自动创建 Java 8 日期时间对象?

How can can I consume a datetime format like this one in jersey? Is it possible to send a datatime String and create Java 8 date time object automatically?

{        
    "email" : "imz.mrz@gmail.com"
    "loginDate" : "2015-04-17T06:06:51.465Z"
} 

#

更新:

我使用的是 Spring boot jersey,并且有其他 jsr 包

I was using Spring boot jersey, and had other jsr packages

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-jersey</artifactId>
 </dependency>

所以我删除了除了 spring-boot-jersey 包之外的所有包.将此注释用于 LocalDateTime

So I removed all the packages except from spring-boot-jersey package. use this annotation for LocalDateTime

  @JsonDeserialize(using =  LocalDateTimeDeserializer.class)

这样我可以使用 ISODate 并将 ISODate() 保存到 mongodb 并生成完整格式的 mongodb LocalDateTime 到前端.

This way I can consume ISODate and save ISODate() to mongodb and produce full formated mongodb LocalDateTime to frontend.

问题解决了.

推荐答案

我看到的几个选项...

选项 1:

假设您有 JAXB 注释支持,Jackson 作为 JSON 提供者...

Couple options I see...

Option 1:

Assuming you have JAXB annotation support with Jackson as the JSON provider...

您可以使用 XmlAdapter.例如

public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {

    @Override
    public LocalDateTime unmarshal(String dateString) throws Exception {
        Instant instant = Instant.parse(dateString);
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        return dateTime;
    }

    @Override
    public String marshal(LocalDateTime dateTime) throws Exception {
        Instant instant = dateTime.toInstant(ZoneOffset.UTC);
        return DateTimeFormatter.ISO_INSTANT.format(instant);
    }
}

参见 Instant API 了解更多信息.

See the Instant API for more information.

然后你可以用适配器注释字段/属性

Then you can just annotate the field/property with the adapter

@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
private LocalDateTime loginDate;

你也可以在包级别声明注解,这样包中的所有使用都将使用适配器,而无需注解.您可以在包内的名为 package-info.java 的文件中执行此操作

You could also declare the annotation at the package level, so that all uses in the package will use the adapter, without the need to annotate. You do so in a file named package-info.java put inside the package

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(type = LocalDateTime.class, 
                        value = LocalDateTimeAdapter.class)
})
package thepackage.of.the.models;

import java.time.LocalDateTime;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;

选项 2:

直接使用 Jackson API.意思是,使用 JsonDeserializerJsonSerializer.例如

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

    @Override
    public LocalDateTime deserialize(JsonParser jp, 
            DeserializationContext dc) throws IOException, JsonProcessingException {
        ObjectCodec codec = jp.getCodec();
        TextNode node = (TextNode)codec.readTree(jp);
        String dateString = node.textValue();
        Instant instant = Instant.parse(dateString);
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        return dateTime;
    } 
}

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    @Override
    public void serialize(LocalDateTime dateTime, JsonGenerator jg, 
            SerializerProvider sp) throws IOException, JsonProcessingException {
        Instant instant = dateTime.toInstant(ZoneOffset.UTC);
        jg.writeString(DateTimeFormatter.ISO_INSTANT.format(instant));
    } 
}

您可以在字段/属性级别应用此功能

You can apply this at the field/property level

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime loginDate; 

或者在ObjectMapper级别(所以你不需要到处注释)

Or at the ObjectMapper level (so you don't need to annotate everywhere)

@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    final ObjectMapper mapper = new ObjectMapper();

    public ObjectMapperContextResolver() {
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        mapper.registerModule(module);
        // add JAXB annotation support if required
        mapper.registerModule(new JaxbAnnotationModule());
    }

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

基本上发生的情况是,用于 ummarshalling/marshalling 的 MessageBodyWriter/MessageBodyReader 将调用 getContext 方法来获取 ObjectMapper

Basically what happens, is that the MessageBodyWriter/MessageBodyReader used for ummarshalling/marshalling, will call the getContext method to get the ObjectMapper

注意:

  • 上述解决方案将从 2007-12-03T10:15:30.00Z 格式解析,如 Instant.parse,并将序列化为相同的格式,如 DateTimeFormatter.ISO_INSTANT

  • The above solutions will parse from the format 2007-12-03T10:15:30.00Z, as documented in Instant.parse, and will serialize to the same format, as documented in DateTimeFormatter.ISO_INSTANT

以上内容还假设您使用 Jackson 作为序列化器.我使用以下依赖项(使用 Jersey 2.16)进行测试

The above is also assuming you are using Jackson as the Serializer. I used the below dependency (with Jersey 2.16) to test

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.16</version>
</dependency>

依赖项使用 JacksonJaxbJsonProvider 来支持 JAXB 注释.如果您使用的是 1.x 等较低版本的 Jersey,如果您启用 POJO 映射功能,则 jersey-json 依赖项应提供 JAXB 注释支持.或者对于 Jersey 1.x,如果你想使用 Jackson 2,你可以使用这个依赖

The dependency uses a JacksonJaxbJsonProvider for JAXB annotation support. If you are using a lower version of Jersey like 1.x, the jersey-json dependency should offer JAXB annotation support, if you enable the POJO mapping feature. Alternatively for Jersey 1.x, if you want to use Jackson 2, you can use this dependency

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.0</version>
</dependency>

这实际上是 jersey-media-json-jackson 使用的.因此,您可以显式注册 JacksonJaxbJsonProvider,或添加 Jackson 包 (com.fasterxml.jackson.jaxrs.json) 以列出要扫描的包

which is actually what is used by jersey-media-json-jackson. So you could explicitly register the JacksonJaxbJsonProvider, or add the Jackson package (com.fasterxml.jackson.jaxrs.json) to list packages to scan

另见:

  • Java 8 LocalDate Jackson 格式.Jackson 模块已经为 Java 8 日期/时间 API 提供了序列化程序.
  • Java 8 LocalDate Jackson format. There is Jackson Module that already comes with serializers for the Java 8 date/time APIs.

这篇关于Jersey 解析 Java 8 日期时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Jersey 解析 Java 8 日期时间

基础教程推荐