这是我的用户类,我要在我的数据库中保存符合 ISO 标准的日期时间。
public class User {
@Id
private String id;
private String email;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime loginDate;
}
这是我的 Jersey Controller :
@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);
}
我怎样才能在 Jersey 中使用像这样的日期时间格式?是否可以发送数据时间 String
并自动创建 Java 8 日期时间对象?
{
"email" : "imz.mrz@gmail.com"
"loginDate" : "2015-04-17T06:06:51.465Z"
}
#
更新:
我用的是Spring boot jersey,还有其他的jsr包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
所以我删除了除 spring-boot-jersey 包之外的所有包。 将此注释用于 LocalDateTime
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
这样我就可以使用 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);
}
}
请参阅 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。意思是,使用 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));
}
}
您可以在字段/属性级别应用它
@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<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
将调用 getContext
方法来获取 对象映射器
注意:
上述解决方案将从
2007-12-03T10:15:30.00Z
格式解析,如Instant.parse
中所述, 并将序列化为相同的格式,如DateTimeFormatter.ISO_INSTANT
中所述以上内容还假设您使用 Jackson 作为序列化器。我使用以下依赖项(使用 Jersey 2.16)进行测试
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.16</version> </dependency>
依赖项使用
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>
这实际上是
jersey-media-json-jackson
使用的。因此,您可以显式注册JacksonJaxbJsonProvider
,或添加 Jackson 包 (com.fasterxml.jackson.jaxrs.json
) 以列出要扫描的包
更新
另请参阅:
- Java 8 LocalDate Jackson format . Jackson 模块已经带有 Java 8 日期/时间 API 的序列化程序。
关于java - Jersey 解析 Java 8 日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29736660/