Jersey解析Java 8日期时间

Jersey解析Java 8日期时间,java,datetime,jersey,jax-rs,java-8,Java,Datetime,Jersey,Jax Rs,Java 8,这是我的用户类,我需要在数据库中保存符合ISO标准的日期时间 public class User { @Id private String id; private String email; @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private LocalDateTime loginDate; } 这是我的球衣控制器: @POST @Consumes("application/

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

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

}
# 更新:

我使用的是SpringBootJersey,还有其他jsr包

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-jersey</artifactId>
 </dependency>
通过这种方式,我可以使用ISODate并将ISODate()保存到mongodb,并将完整格式的mongodb LocalDateTime生成到前端

问题已解决。

我看到了几个选项。。。 备选案文1: 假设您有JAXB注释支持,Jackson作为JSON提供程序

您可以使用
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);
    }
}
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));
    } 
}
您还可以在包级别声明注释,以便包中的所有使用都将使用适配器,而无需注释。您可以在名为
package info.java
的文件中执行此操作,该文件放在包中

@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: 直接使用jacksonapi。也就是说,使用
JsonSerializer
JsonSerializer
。比如说

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);
    }
}
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));
    } 
}
或者在
ObjectMapper
级别(因此不需要到处注释)

依赖项使用
JacksonJaxbJsonProvider
来支持JAXB注释。如果您使用的是Jersey的较低版本,比如1.x,那么如果您启用POJO映射功能,
Jersey json
依赖项应该提供JAXB注释支持。或者,对于Jersey 1.x,如果您想使用Jackson 2,您可以使用此依赖项

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

com.fasterxml.jackson.jaxrs
. Jackson模块已经为java8日期/时间api提供了序列化程序

可能有人编写了一个库来执行此操作,如果没有,您可能需要编写自己的自定义转换器。请看非常描述性的答案,我选择选项2。现在我可以用这种格式“loginDate”将它保存在mongodb中:{“dateTime”:ISODate(“2015-04-17T10:06:51.465Z”),“offset”:{“U id”:“Z”,“totalSeconds”:0}}但是,当尝试序列化它时,它不起作用。它给了我“在实体类java.time.OffsetDateTime上找不到将构造函数参数绑定到的属性null!”更改了它的LocalDateTime,在尝试检索对象“在实体类java.time.LocalDateTime上找不到将构造函数参数绑定到的属性null”时仍然出现错误“它对我来说工作正常”。您使用的是哪种配置?注释或对象映射器?在
ContextResolver
中,我忘记了注册
SimpleModule
:-)
mapper.registerModule(模块)进行了编辑。注释应该可以工作。我已经测试了上面的所有选项。至于如何使用
ObjectMapper
,如果您正在扫描所有资源类(用
@Path
注释的资源类),则应使用
@Provider
注释自动拾取
上下文解析器。不需要额外的配置。我将在
getContext
方法中放置一个print语句,以查看序列化时是否调用它。让我知道。你也尝试过反序列化吗?这样行吗?
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime loginDate; 
@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;
    }  
}
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.16</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.0</version>
</dependency>