lib*_*dev 9 java jackson jsr310 jersey-2.0
我正在尝试编组包含ISO格式的时间戳的响应,如下所示:
{
...
"time" : "2014-07-02T04:00:00.000000Z"
...
}
Run Code Online (Sandbox Code Playgroud)
进入ZonedDateTime我的域模型对象中的字段.最终,如果我使用在以下片段中注释的解决方案,它会起作用.在SO上有许多类似的问题,但我想得到一个具体的答案,另一种使用的方法JacksonJsonProvider有ObjectMapper + JavaTimeModule什么问题?
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
Client client = ClientBuilder.newBuilder()
// .register(new ObjectMapperContextResolver(){
// @Override
// public ObjectMapper getContext(Class<?> type) {
// ObjectMapper mapper = new ObjectMapper();
// mapper.registerModule(new JavaTimeModule());
// return mapper;
// }
// })
.register(provider)
.register(JacksonFeature.class)
.build();
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
javax.ws.rs.client.ResponseProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.ZonedDateTime: no String-argument constructor/factory method to deserialize from String value ('2017-02-24T20:46:05.000000Z')
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@53941c2f
Run Code Online (Sandbox Code Playgroud)
项目依赖项是:
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.7'
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-core:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-databind:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.8.7'
compile 'org.glassfish.jersey.core:jersey-client:2.25.1'
Run Code Online (Sandbox Code Playgroud)
编辑
反序列化发生在这里:
CandlesResponse<BidAskCandle> candlesResponse = webTarget.request()
.header(HttpHeaders.AUTHORIZATION,"Bearer "+token)
.accept(MediaType.APPLICATION_JSON)
.get(new GenericType<CandlesResponse<BidAskCandle>>(){});
Run Code Online (Sandbox Code Playgroud)
Pau*_*tha 10
最终,如果我使用以下代码段中注释的解决方案,它就可以工作。
首先,您在列表中也缺少一个依赖项,这就是问题所在。
jersey-media-json-jackson
此模块取决于具有的本地Jackson模块JacksonJsonProvider。当您注册时JacksonFeature随附的时jersey-media-json-jackson,它会注册自己的JacksonJaxbJsonProvider,它似乎优先于您提供的任何东西。
当您使用时ContextResolver,JacksonJsonProvider实际进行查找ContextResolver并使用它来解析ObjectMapper。这就是为什么它起作用。无论您使用JacksonFeature还是注册了自己的JacksonJsonProvider(无需ObjectMapper为其配置),ContextResovler都可以使用。
关于jersey-media-json-jackson模块的另一件事,它参与了Jersey的自动发现机制的注册,该机制可以注册JacksonFeature。因此,即使您没有显式注册它,它仍然会被注册。避免被注册的唯一方法是:
jersey-media-json-jackson。只需使用Jackson本机模块jackson-jaxrs-json-provider。不过,与此相关的是,jersey-media-json-jackson会在本机模块的顶部添加一些功能,因此您将失去这些功能。尚未测试,但似乎如果使用JacksonJaxbJsonProvider代替JacksonJsonProvider,它可能会起作用。如果您查看的来源JacksonFeature,则会看到它检查已注册的内容JacksonJaxbJsonProvider。如果有一个,它不会注册它自己的。
我不确定的一件事是自动发现。注册的顺序(如果会影响它是否抓住了您的注册)JacksonJaxbJsonProvider。您可以测试的东西。
从我的宠物项目:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
public WebTarget getTarget(URI uri) {
Client client = ClientBuilder
.newClient()
.register(JacksonConfig.class);
return client.target(uri);
}
Run Code Online (Sandbox Code Playgroud)
在哪里
@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public JacksonConfig() {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@Override
public ObjectMapper getContext(Class<?> aClass) {
return objectMapper;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10282 次 |
| 最近记录: |