2012-02-21 9 views
46

Spring RestTemplateで使用されているjacksonマッパーのSerializationConfig.Feature ...プロパティを更新したいと思います。どのように入手できますか、どこで設定できますか。 、ターンでRestTemplateを使用するときに、内部ジャクソンマッパーを設定するにはどうすればよいですか?

this.messageConverters.add(new ByteArrayHttpMessageConverter()); 
this.messageConverters.add(new StringHttpMessageConverter()); 
this.messageConverters.add(new ResourceHttpMessageConverter()); 
this.messageConverters.add(new SourceHttpMessageConverter()); 
this.messageConverters.add(new XmlAwareFormHttpMessageConverter()); 
if (jaxb2Present) { 
    this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); 
} 
if (jacksonPresent) { 
    this.messageConverters.add(new MappingJacksonHttpMessageConverter()); 
} 
if (romePresent) { 
    this.messageConverters.add(new AtomFeedHttpMessageConverter()); 
    this.messageConverters.add(new RssChannelHttpMessageConverter()); 
} 

MappingJacksonHttpMessageConverter直接ObjectMapperインスタンスを作成する:

答えて

64

デフォルトRestTemplateコンストラクタはHttpMessageConverter Sのセットを登録します。このコンバータを見つけてObjectMapperを置き換えるか、新しいものを前もって登録してください。これは動作するはずです:遷移は本当に1ではないことを

<bean id="restOperations" class="org.springframework.web.client.RestTemplate"> 
    <property name="messageConverters"> 
     <util:list> 
      <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
       <property name="objectMapper" ref="customObjectMapper"/> 
      </bean> 
     </util:list> 
    </property> 
</bean> 

<bean id="customObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/> 

注:XMLでは

@Bean 
public RestOperations restOperations() { 
    RestTemplate rest = new RestTemplate(); 
    //this is crucial! 
    rest.getMessageConverters().add(0, mappingJacksonHttpMessageConverter()); 
    return rest; 
} 

@Bean 
public MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter() { 
    MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter(); 
    converter.setObjectMapper(myObjectMapper()); 
    return converter; 
} 

@Bean 
public ObjectMapper myObjectMapper() { 
    //your custom ObjectMapper here 
} 

それはこれらの線に沿って何かである1 - 私は明示的にXMLでmessageConvertersリストを作成する必要が付きながら、 @Configurationアプローチ私は既存のものを参照し、単純に修正することができます。しかし、これはうまくいくはずです。

+0

これをXMLに変換できると感謝しています。本当にこれを試してみたいが、設定方法は不明だ。どうもありがとう! – Justin

+2

@ジャスティン:私のゲストです - 更新された答えを見てください。 –

+4

これはちょうどバージョンの違いによるものかどうかはわかりませんが、ジャクソンのコンバータクラスの正しい名前はMappingJackson * 2 * HttpMessageConverterです。 – nbrooks

3

RestTemplateは、デフォルトのメッセージコンバータを初期化します。 MappingJackson2HttpMessageConverterは独自のBeanに置き換える必要があります。使用するオブジェクトマッパーを使用する必要があります。これが私の仕事:

ObjectMapper objectMapper = new ObjectMapper(); 
// configure your ObjectMapper here 

RestTemplate restTemplate = new RestTemplate();  

MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); 
messageConverter.setPrettyPrint(false); 
messageConverter.setObjectMapper(objectMapper); 
restTemplate.getMessageConverters().removeIf(m -> m.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName())); 
restTemplate.getMessageConverters().add(messageConverter); 
+0

'myObjectMapper()'のようにメソッド名を指定するのは重要ですが、 'objectMapper()'だけではありません。なんらかの理由で、メソッドが呼び出されることはなく、デフォルトの 'ObjectMapper'を取得するようです。 – herman

18

、あなたはこのような何か(のJava 8)を行うことができますカスタムのシリアライザ/デシリアライザジャクソンModule次のように、あなたがRestTemplateのデフォルトMappingJackson2HttpMessageConverterから既存のObjectMapperに直接モジュールを登録したい場合がありますこと(DIなしの例が、DIを使用している場合も同様です):

SimpleModule module = new SimpleModule(); 
    module.addSerializer(...); 
    module.addDeserializer(...); 

    MappingJackson2HttpMessageConverter messageConverter = restTemplate.getMessageConverters().stream() 
        .filter(MappingJackson2HttpMessageConverter.class::isInstance) 
        .map(MappingJackson2HttpMessageConverter.class::cast) 
        .findFirst().orElseThrow(() -> new RuntimeException("MappingJackson2HttpMessageConverter not found")); 
    messageConverter.getObjectMapper().registerModule(module); 

これにより、元のObjectMapper(SpringのJackson2ObjectMapperBuilderのように)の設定を置き換えるのではなく、完了することができます。

1

は、他の答えを完了させるために:あなたのObjectMapperがちょうど登録する場合は、春のIOCを使用していない場合

@Bean 
public RestTemplate restTemplate() { 
    final RestTemplate restTemplate = new RestTemplate(); 

    //find and replace Jackson message converter with our own 
    for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) { 
     final HttpMessageConverter<?> httpMessageConverter = restTemplate.getMessageConverters().get(i); 
     if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter){ 
      restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter); 
     } 
    } 

    return restTemplate; 
} 

@Bean 
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
    converter.setObjectMapper(myObjectMapper()); 
    return converter; 
} 

@Bean 
public ObjectMapper myObjectMapper() { 
    // return your own object mapper 
} 
関連する問題