【问题标题】:Using Jersey client, problems with Java 8 Date API (Jsr310)使用 Jersey 客户端,Java 8 Date API (Jsr310) 的问题
【发布时间】:2015-12-03 18:11:58
【问题描述】:

我正在使用 jersey 客户端执行一个小 PoC 以使用 REST 服务,但我遇到了 LocalDateTime 格式的字段问题。 REST 服务响应是这样的:

{
    "id": 12,
    "infoText": "Info 1234",
    "creationDateTime": "2001-12-12T13:40:30"
}

还有我的实体类:

package com.my.poc.jerseyclient;

import java.time.LocalDateTime;

public class Info {

    private Long id;
    private String infoText;
    private LocalDateTime creationDateTime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getInfoText() {
        return infoText;
    }

    public void setInfoText(String infoText) {
        this.infoText = infoText;
    }

    public LocalDateTime getCreationDateTime() {
        return creationDateTime;
    }

    public void setCreationDateTime(LocalDateTime creationDateTime) {
        this.creationDateTime = creationDateTime;
    }

}

我的 pom.xml 中的依赖项:

<dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.21</version>
        </dependency>

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

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.6.1</version>
        </dependency>
    </dependencies>

我的代码使用 jersey 客户端执行 GET /api/info/123:

Client client = ClientBuilder.newClient(new ClientConfig().register(JacksonJsonProvider.class);
WebTarget webTarget = client.target("http://localhost:8080/api/").path("info/");
Response response = webTarget.path("123").request(MediaType.APPLICATION_JSON_TYPE).get();
System.out.println("GET Body (object): " + response.readEntity(Info.class));

我遇到了这样的异常:

...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDateTime] from String value ('2001-12-12T13:40:30'); no single-String constructor/factory method
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@21b2e768; line: 1, column: 32] (through reference chain: com.my.poc.jerseyclient.Info["creationDateTime"])
...

我错过了什么?我用 RestTemplate(Spring rest 客户端)尝试了这个,它无需任何配置即可完美运行。

【问题讨论】:

    标签: java rest jersey jackson jsr310


    【解决方案1】:

    jsr310 模块仍然需要向 Jackson 注册。您可以在ContextResolver 中以seen here 的形式执行此操作,在其中将Jsr310Module 注册为ObjectMapper

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    

    您然后向客户注册ContextResolver。将会发生的是JacksonJsonProvider 应该调用getContext 方法,并检索ObjectMapper 以用于(反)序列化。

    您也可以在服务器端使用相同的ContextResolver。如果您只需要客户端上的此功能,另一种方法是使用ObjectMapper 简单地构造JacksonJsonProvider。简单一点

    new JacksonJsonProvider(mapper)
    

    【讨论】:

    • 它有效,谢谢!我在想我必须以某种方式向客户注册它,但我不知道如何。
    【解决方案2】:

    将所有内容放在一起以实现客户端功能:

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    
    JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
    Client client = ClientBuilder.newClient(new ClientConfig().register(provider));
    

    【讨论】:

    • 感谢您如此清晰、干净地陈述答案。请注意,自 Jackson 2.6.0 起,JSR310Module 已弃用,取而代之的是 JavaTimeModule
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    相关资源
    最近更新 更多