2012-02-21 13 views
46

मैं SerializationConfig.Feature ... स्प्रिंग RestTemplate द्वारा उपयोग किए जाने वाले जैक्सन मैपर के गुणों को अपडेट करना चाहता हूं, कोई विचार यह है कि मैं इसे कैसे प्राप्त कर सकता हूं या जहां मैं इसे कॉन्फ़िगर कर सकता/सकती हूं।RestTemplate का उपयोग करते समय हम आंतरिक जैक्सन मैपर को कैसे कॉन्फ़िगर कर सकते हैं?

उत्तर

64

डिफ़ॉल्ट RestTemplate निर्माता HttpMessageConverter रों का एक सेट पंजीकृत करता है:

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 उदाहरण पैदा करता है। आप या तो इस कनवर्टर को ढूंढ सकते हैं और ObjectMapper को प्रतिस्थापित कर सकते हैं या इससे पहले एक नया पंजीकरण कर सकते हैं। यह काम करना चाहिए:

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

ध्यान दें कि संक्रमण वास्तव में 1 नहीं है::

@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

यदि आप इसे एक्सएमएल में अनुवाद कर सकते हैं तो मैं आभारी रहूंगा। वास्तव में यह कोशिश करना चाहते हैं लेकिन यह सुनिश्चित नहीं है कि इसे कैसे कॉन्फ़िगर करें। बहुत धन्यवाद! – Justin

+2

@ जस्टिन: मेरा अतिथि बनें - अद्यतन उत्तर देखें। –

+4

यह सुनिश्चित नहीं है कि यह केवल एक संस्करण अंतर के कारण है, लेकिन मेरा मानना ​​है कि जैक्सन कनवर्टर क्लास का सही नाम मैपिंग जैक्सन * 2 * एचटीपी मैसेज कनवर्टर – nbrooks

3

RestTemplate इसके डिफ़ॉल्ट संदेश कन्वर्टर्स को आरंभ करेगा। आपको अपने स्वयं के बीन के साथ MappingJackson2HttpMessageConverter को प्रतिस्थापित करना चाहिए, जिसे आप ऑब्जेक्ट मैपर का उपयोग करना चाहते हैं जिसका उपयोग करना चाहते हैं। यह मेरे लिए काम किया:

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() 'नहीं। किसी कारण से ऐसा लगता है कि विधि कभी नहीं बुलाई जाती है और आपको डिफ़ॉल्ट 'ऑब्जेक्टमैपर' मिलता है। – herman

18

आप स्प्रिंग आईओसी उपयोग नहीं कर रहे हैं, तो आप कुछ इस तरह (जावा 8) क्या कर सकते हैं कस्टम serializers/deserializers साथ जैक्सन Module, आप के रूप में (डीआई के बिना उदाहरण लेकिन एक ही डि का उपयोग कर यदि लागू होता है) इस प्रकार है RestTemplate के डिफ़ॉल्ट MappingJackson2HttpMessageConverter से मौजूदा ObjectMapper पर सीधे अपने मॉड्यूल रजिस्टर करने के लिए चाहते हो सकता है:

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 (वसंत केद्वारा किए गए अनुसार) की कॉन्फ़िगरेशन को पूरा करने की बजाय आपको इसकी अनुमति देगा।

1

अन्य उत्तर पूरा करने के लिए: अगर आपके ObjectMapper सिर्फ एक पंजीकृत करता

@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 
} 
संबंधित मुद्दे