使用 Jersey 客户端,问题 Java 8 Date API (Jsr310)
Using Jersey client, problems with Java 8 Date API (Jsr310)
我正在使用 jersey 客户端进行一些 PoC 以使用 REST 服务,但我在使用 LocalDateTime 格式的字段时遇到了问题。
REST 服务响应是这样的:
{
"id": 12,
"infoText": "Info 1234",
"creationDateTime": "2001-12-12T13:40:30"
}
还有我的实体class:
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>
我的代码使用球衣客户端执行 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 client) 尝试了这个,它在没有任何配置的情况下工作得很好。
jsr310模块还需要在Jackson注册。您可以在 ContextResolver
as 中执行此操作,在其中将 Jsr310Module
注册为 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
然后您向客户端注册 ContextResolver
。将会发生的是 JacksonJsonProvider
应该调用 getContext
方法,并检索要用于(反)序列化的 ObjectMapper
。
您也可以在服务器端使用相同的 ContextResolver
。如果您只在客户端需要此功能,另一种方法是用 ObjectMapper
简单地构造 JacksonJsonProvider
。简单一点
new JacksonJsonProvider(mapper)
将它们放在一起以实现客户端功能:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
Client client = ClientBuilder.newClient(new ClientConfig().register(provider));
我正在使用 jersey 客户端进行一些 PoC 以使用 REST 服务,但我在使用 LocalDateTime 格式的字段时遇到了问题。 REST 服务响应是这样的:
{
"id": 12,
"infoText": "Info 1234",
"creationDateTime": "2001-12-12T13:40:30"
}
还有我的实体class:
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>
我的代码使用球衣客户端执行 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 client) 尝试了这个,它在没有任何配置的情况下工作得很好。
jsr310模块还需要在Jackson注册。您可以在 ContextResolver
as Jsr310Module
注册为 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
然后您向客户端注册 ContextResolver
。将会发生的是 JacksonJsonProvider
应该调用 getContext
方法,并检索要用于(反)序列化的 ObjectMapper
。
您也可以在服务器端使用相同的 ContextResolver
。如果您只在客户端需要此功能,另一种方法是用 ObjectMapper
简单地构造 JacksonJsonProvider
。简单一点
new JacksonJsonProvider(mapper)
将它们放在一起以实现客户端功能:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
Client client = ClientBuilder.newClient(new ClientConfig().register(provider));