2016-06-28 8 views
1

私は非常によく知られた問題に直面していますが、解決策はありません。クイックヘルプは感謝します。ジャクソンとのJava 8 LocalDate変換が機能しません

MVCコントローラから、というモデルオブジェクトをフィールドの1つとして返すRESTサービスを呼び出しています。 JacksonJAXbJSONProviderは、Localdateオブジェクトを解析しません。私は以下のようにカスタムMapperを書いた。依存関係はpom.xmlに追加されている。その他の必要な依存関係も(ジャクソンデータバインド、コア、注釈)

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

カスタムObjectMapperクラス追加されます。これはJava 8 LocalDate Jackson format

マイspring.xmlで示唆された

public class LocalDateObjectMapperContextResolver extends ObjectMapper{ 
    @Provider 
    public LocalDateObjectMapperContextResolver() { 

     registerModule(new JavaTimeModule()); 
     //findAndRegisterModules(); 
     configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 
    } 

} 

(MVCのための設定が含まれていますコントローラなど)は、以下のように自動的に変換を行う1つのマッパーを既に設定しています。

<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サービスに接続するスタブファイルです。私はまた、上記のdidnotの仕事の後に以下のようにプロバイダを提供しようとしましたが、ここでも運はありません。

<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> 

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

なぜあなたのSptingコンテキストでボットカスタムと元のObjectMapperを宣言していますか?カスタムはすでにObjectMapperを拡張しているため、カスタムオブジェクトマッパーを宣言するだけで済みます。メッセージコンバーターを選択して間違ったオブジェクトマッパーを使用すると、Springが混乱する可能性があります。 – Matt

+0

返事ありがとうMatt、あなたの主張に同意します。しかし、私はそれを理由でやった、他の多くのmvcコントローラがデフォルトのもの(codehausから)を使用する既存のアプリケーションの拡張に取り組んでいます。私が拡張しているものは 'fasterxml'( 'LocalDate'サポート)私はそれを 'MappingJackson2HttpMessageConverter'に渡します testingviewのために試してみましょうか? – Surinder

+0

Ok、2つの異なるバージョンのJacksonを同時に使用していますか?クラスが異なるパッケージに入っていても、一般的には悪い習慣です。これをクリアするには、旧バージョンと他のObjectMapperを削除してください。 – Matt

答えて

1

の下に取得しています。拡張されたObjectMapperは新しいモジュールを作成し、それにシリアライザとデシリアライザを追加し、最後にObjectmapperにモジュールを登録し、JacksonJaxbJsonProviderコンストラクタの最初の引数としてobjectmapperを渡しました、2番目の引数はデフォルトの注釈です。 以下は私のコードです。

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> 

クライアント側configarion

<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は、以下のようにLOCALDATEに戻ってJSON文字列を解析し、jaxrsに プロバイダの下にこれを登録するには書くことができます

:サーバー

MyCustomParamHandler implements Paramhandler<Localdate>{ 

LocalDate fromString(String jsonString){ 
      return LocalDate.parse(jsonString); 
    } 
} 

乾杯!