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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:49:29  来源:igfitidea点击:

Jersey parsing Java 8 date time

javadatetimejerseyjax-rsjava-8

提问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 Stringand 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.javaput inside the package

您还可以在包级别声明注解,以便包中的所有使用都将使用适配器,而无需进行注解。您在名为package-info.javaput 包内的文件中执行此操作

@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 JsonDeserializerand JsonSerializer. For example

直接使用 Hymanson API。意思是,使用 aJsonDeserializerJsonSerializer。例如

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 ObjectMapperlevel (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/MessageBodyReaderused for ummarshalling/marshalling, will call the getContextmethod 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 in Instant.parse, and will serialize to the same format, as documented in DateTimeFormatter.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 HymansonJaxbJsonProviderfor JAXB annotation support. If you are using a lower version of Jersey like 1.x, the jersey-jsondependency 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 the HymansonJaxbJsonProvider, 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:

也可以看看: