泽西解析Java 8日期时间 [英] Jersey parsing Java 8 date time

查看:395
本文介绍了泽西解析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"
} 





更新:

#

Update:

我正在使用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注释支持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 获取更多信息。

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

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:



API直接意思是使用 JsonDeserializer JsonSerializer 。例如

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));
    } 
}

您可以在字段/属性级别/ p>

You can apply this at the field/property level

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

或在$ code> 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;
    }  
}

基本上会发生什么,就是 MessageBodyWriter / MessageBodyReader 用于ummarshalling / marshalling,将调用 getContext 方法获取 ObjectMapper

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

注意:

  • 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作为Serializer。我使用以下依赖关系(与泽西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,则如果启用了POJO映射功能,那么 jersey-json 依赖关系应该提供JAXB注释支持。另外对于泽西1.x,如果你想使用杰克逊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 format. There is Jackson Module that already comes with serializers for the Java 8 date/time APIs.

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

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