与Jackson的Java 8 LocalDate转换不起作用

时间:2016-06-28 18:02:02

标签: json jackson jax-rs

我面临着一个非常着名的问题,但没有解决方案对我有用。任何快速帮助都将不胜感激。

从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?)

1 个答案:

答案 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);
    }
}

干杯!

相关问题