Jersey 解析 Java 8 日期时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29736660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jersey parsing Java 8 date time
提问by Imtiaz Mirza
This is my user class, and I to save ISO compliant date time in my database.
这是我的用户类,我将在我的数据库中保存 ISO 兼容的日期时间。
public class User {
@Id
private String id;
private String email;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime loginDate;
}
Here is my Jersey controller:
这是我的 Jersey 控制器:
@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);
}
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?
我怎样才能在球衣中使用这样的日期时间格式?是否可以发送String
数据时间并自动创建 Java 8 日期时间对象?
{
"email" : "[email protected]"
"loginDate" : "2015-04-17T06:06:51.465Z"
}
#
Update:
更新:
I was using Spring boot jersey, and had other jsr packages
我使用的是 Spring Boot jersey,还有其他的 jsr 包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
So I removed all the packages except from spring-boot-jersey package. use this annotation for LocalDateTime
所以我删除了除了 spring-boot-jersey 包之外的所有包。将此注释用于 LocalDateTime
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
This way I can consume ISODate and save ISODate() to mongodb and produce full formated mongodb LocalDateTime to frontend.
这样我就可以使用 ISODate 并将 ISODate() 保存到 mongodb 并生成完整格式的 mongodb LocalDateTime 到前端。
Problem solved.
问题解决了。
回答by Paul Samsotha
Couple options I see...
我看到的几个选项......
Option 1:
选项1:
Assuming you have JAXB annotation support with Hymanson as the JSON provider...
假设你有 JAXB 注释支持,Hyman逊作为 JSON 提供者......
You could use an XmlAdapter
. For example
你可以使用一个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);
}
}
See the Instant APIfor more information.
有关更多信息,请参阅Instant API。
Then you can just annotate the field/property with the adapter
然后您可以使用适配器注释字段/属性
@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
private LocalDateTime loginDate;
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
您还可以在包级别声明注解,以便包中的所有使用都将使用适配器,而无需进行注解。您在名为package-info.java
put 包内的文件中执行此操作
@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;
Option 2:
选项 2:
Use the Hymanson APIs directly. Meaning, use a JsonDeserializer
and JsonSerializer
. For example
直接使用 Hymanson API。意思是,使用 aJsonDeserializer
和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));
}
}
You can apply this at the field/property level
您可以在字段/属性级别应用它
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime loginDate;
Or at the ObjectMapper
level (so you don't need to annotate everywhere)
或者在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;
}
}
Basically what happens, is that the MessageBodyWriter
/MessageBodyReader
used for ummarshalling/marshalling, will call the getContext
method to get the ObjectMapper
基本上会发生什么,就是MessageBodyWriter
/MessageBodyReader
用于ummarshalling /编组,将调用getContext
方法来获取ObjectMapper
Note:
笔记:
The above solutions will parse from the format
2007-12-03T10:15:30.00Z
, as documented inInstant.parse
, and will serialize to the same format, as documented inDateTimeFormatter.ISO_INSTANT
The above is also assuming you are using Hymanson 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-Hymanson</artifactId> <version>2.16</version> </dependency>
The dependency uses a
HymansonJaxbJsonProvider
for JAXB annotation support. If you are using a lower version of Jersey like 1.x, thejersey-json
dependency should offer JAXB annotation support, if you enable the POJO mapping feature. Alternatively for Jersey 1.x, if you want to use Hymanson 2, you can use this dependency<dependency> <groupId>com.fasterxml.Hymanson.jaxrs</groupId> <artifactId>Hymanson-jaxrs-json-provider</artifactId> <version>2.4.0</version> </dependency>
which is actually what is used by
jersey-media-json-Hymanson
. So you could explicitly register theHymansonJaxbJsonProvider
, or add the Hymanson package (com.fasterxml.Hymanson.jaxrs.json
) to list packages to scan
上述解决方案将从格式解析
2007-12-03T10:15:30.00Z
,如在记录Instant.parse
,并且将序列化到相同的格式,记录在DateTimeFormatter.ISO_INSTANT
以上还假设您使用 Hymanson 作为序列化程序。我使用以下依赖项(使用 Jersey 2.16)进行测试
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-Hymanson</artifactId> <version>2.16</version> </dependency>
该依赖项使用
HymansonJaxbJsonProvider
用于 JAXB 注释支持。如果您使用的是较低版本的 Jersey,如 1.x,则jersey-json
如果您启用 POJO 映射功能,则依赖项应提供 JAXB 注释支持。或者对于 Jersey 1.x,如果你想使用 Hymanson 2,你可以使用这个依赖<dependency> <groupId>com.fasterxml.Hymanson.jaxrs</groupId> <artifactId>Hymanson-jaxrs-json-provider</artifactId> <version>2.4.0</version> </dependency>
这实际上是
jersey-media-json-Hymanson
. 因此,您可以显式注册HymansonJaxbJsonProvider
,或添加 Hymanson 包 (com.fasterxml.Hymanson.jaxrs.json
) 以列出要扫描的包
UPDATE
更新
See Also:
也可以看看:
- Java 8 LocalDate Hymanson format. There is Hymanson Module that already comes with serializers for the Java 8 date/time APIs.
- Java 8 LocalDate Hymanson 格式。Java 8 日期/时间 API 的序列化程序已经附带了 Hymanson 模块。