Jersey解析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/json") @Produces("application/json") public Response create( User user) { Map apiResponse = new HashMap(); Map response = new HashMap(); user = (User) userService.create(user); } 

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

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

更新:

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

   org.springframework.boot spring-boot-starter-jersey  

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

  @JsonDeserialize(using = LocalDateTimeDeserializer.class) 

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

问题解决了。

我看到几个选项……

选项1:

假设你有jackson作为JSON提供者的JAXB注释支持……

您可以使用XmlAdapter 。 例如

 public class LocalDateTimeAdapter extends XmlAdapter { @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 。

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

 @XmlJavaTypeAdapter(LocalDateTimeAdapter.class) private LocalDateTime loginDate; 

您还可以在包级别声明注释,以便包中的所有用法都将使用适配器,而无需注释。 您可以在包中放入名为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:

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

 public class LocalDateTimeDeserializer extends JsonDeserializer { @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 { @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)); } } 

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

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

或者在ObjectMapper级别(所以你不需要在任何地方注释)

 @Provider @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class ObjectMapperContextResolver implements ContextResolver { 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

注意:

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

  • 以上也假设你使用Jackson作为Serializer。 我使用下面的依赖项(使用Jersey 2.16)进行测试

      org.glassfish.jersey.media jersey-media-json-jackson 2.16  

    依赖项使用JacksonJaxbJsonProvider进行JAXB注释支持。 如果您使用较低版本的Jersey(如1.x),则如果启用POJO映射function,则jersey-json依赖项应提供JAXB注释支持。 或者对于Jersey 1.x,如果你想使用Jackson 2,你可以使用这种依赖

      com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider 2.4.0  

    这实际上是jersey-media-json-jackson 。 所以你可以显式注册JacksonJaxbJsonProvider ,或者添加Jackson包( com.fasterxml.jackson.jaxrs.json )来列出要扫描的包


UPDATE

也可以看看:

  • Java 8 LocalDate Jackson格式 。 jackson模块已经附带了Java 8日期/时间API的序列化程序。