我面临着一个非常着名的问题,但没有解决方案对我有用。任何快速帮助都将不胜感激。
从MVC控制器,我调用REST服务,它返回带有LocalDate
的Model对象作为其中一个字段。 JacksonJAXbJSONProvider
不解析Localdate
对象。我在下面编写了自定义Mapper并在pom.xml
中添加了依赖项。还添加了其他必需的依赖项(jackson数据绑定,核心,注释)
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.1</version>
</dependency>
自定义ObjectMapper
类:
public class LocalDateObjectMapperContextResolver extends ObjectMapper{
@Provider
public LocalDateObjectMapperContextResolver() {
registerModule(new JavaTimeModule());
//findAndRegisterModules();
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
}
Java 8 LocalDate Jackson format
中建议这样做我的spring.xml(包含MVC控制器的配置等...)已经配置了一个映射器,它自动进行转换,如下所示
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
p:objectMapper-ref="myobjectMapper"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"
p:objectMapper-ref="objectMapper"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="objectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>
<bean id="myobjectMapper" class="mypackage.LocalDateObjectMapperContextResolver"/>
下面是连接到REST服务的存根文件。在上面没有工作之后我也尝试提供如下提供者,但是这里也没有运气。
<jaxrs:client id="testclient"
serviceClass="package1.RESTService"
username="abc"
password="abc"
address="$serviceURL">
<jaxrs:features>
<bean class="org.apache.cxf.transport.common.gzip.GZIPFeature"/>
<cxf:logging/>
</jaxrs:features>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="mypackage.LocalDateObjectMapperContextResolver"/>
</jaxrs:providers>
</jaxrs:client>
现在如何配置我刚编写的Context解析器,以便我能够转换LocalDate。
我做错了什么?
我正处于异常
之下No suitable constructor found for type [simple type, class java.time.LocalDate]: can not instantiate from JSON object (need to add/enable type information?)
答案 0 :(得分:1)
我解决了。扩展ObjectMapper,创建新模块,向其添加序列化器和反序列化器,最后将模块注册到Objectmapper,并将对象映射器作为JacksonJaxbJsonProvider构造函数中的第一个参数传递,传递的第二个参数是默认注释。 以下是我的代码。
public class MyObjectMapper extends ObjectMapper {
public MyObjectMapper() {
SimpleModule sm = new SimpleModule("SomeName", new Version(1,1,1,""));
sm.addSerializer(LocalDate.class, new JsonSerializer<LocalDate>() {
@Override
public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
ToStringSerializer.instance.serialize(value, jgen, provider);
}
});
sm.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
@Override
public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
ToStringSerializer.instance.serialize(value, jgen, provider);
}
});
sm.addDeserializer(LocalDate.class, new JsonDeserializer<LocalDate>() {
@Override
public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return LocalDate.parse(jp.getText());
}
});
sm.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return LocalDateTime.parse(jp.getText());
}
});
registerModule(sm);
}
服务器端配置:
<bean id="mapper" class="mymapperpkg.MyObjectMapper"/>
<jaxrs:server>
......
.....
<jaxrs:serviceBeans>....</jaxrs:serviceBeans>
......
......
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
<constructor-arg index="0" ref="mapper"/>
<constructor-arg index="1">
<util:constant static-field="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS"/>
</constructor-arg>
</bean> -->
</jaxrs:server>
客户端配置
<bean id="mapper" class="mymapperpkg.MyObjectMapper"/>
<jaxrs:client id="deliveryItemClient"
serviceClass="servicepkg.YourRESTServiceClass"
username="adadsad"
password="asdasdasd"
address="adresss to deployed service">
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
<constructor-arg index="0" ref="mapper"/>
<constructor-arg index="1">
<util:constant static-field="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS"/>
</constructor-arg>
</bean>
</jaxrs:providers>
</jaxrs:client>
这是REST应用程序生成LocalDate的时候。
如果REST应用程序正在使用LocalDate,您可以编写ParamHanlder来将json字符串解析回LocalDate,如下所示并在 jaxrs中的提供者:服务器
MyCustomParamHandler implements Paramhandler<Localdate>{
LocalDate fromString(String jsonString){
return LocalDate.parse(jsonString);
}
}
干杯!