2012-09-20 18 views
8

मेरे पास जेएक्सबी एनोटेशन के साथ कई इकाइयां हैं जिन्हें मैं एक संदेश कनवर्टर का उपयोग कर JSON में कनवर्ट करना चाहता हूं।रजिस्ट्रार मैपिंग जैकसन 2 एचटीपीएमसेज कनवर्टर वसंत 3.1.2 में जेएक्सबी एनोटेशन

मुझे पता है कि मेरी ObjectMapper कि JAXB एनोटेशन पढ़ता काम करता है:

String correctJsonText = jacksonObjectMapper.writeValueAsString(entityWithJAXB); 

लेकिन जब मैं अपने बाकी सेवा को कॉल डिफ़ॉल्ट पंजीकृत MappingJacksonHttpMessageConverter (जो JAXB पढ़ने के लिए कॉन्फ़िगर नहीं है) पर कब्जा करने लगता है - जिसका परिणाम चक्रीय संदर्भों के कारण एक स्टैक ओवरफ्लो जब @XmlTransient को अनदेखा किया जाता है ...

मैपिंग जैक्सन 2HttpMessageConverter का उपयोग करने के लिए मैं वसंत को कैसे कॉन्फ़िगर कर सकता हूं?

वर्तमान कॉन्फ़िगरेशन

<mvc:annotation-driven> 
    <mvc:message-converters register-defaults="false"> 
     <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper" ref="jacksonObjectMapper" /> 
      <property name="supportedMediaTypes"> 
       <list> 
        <bean class="org.springframework.http.MediaType"> 
         <constructor-arg index="0" value="application" /> 
         <constructor-arg index="1" value="json" /> 
         <constructor-arg index="2" value="UTF-8" /> 
        </bean> 
       </list> 
      </property> 

     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

<bean id="jaxbAnnotationInspector" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector" /> 

<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"> 
    <property name="annotationIntrospector" ref="jaxbAnnotationInspector" /> 
</bean> 

बाकी सेवा

@RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json;charset=UTF-8") 
public @ResponseBody EntityWithJAXB readEntityWithJAXB(@PathVariable int id, Model model) { 
    return entityService.getById(id); 
} 

निर्भरता

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-core</artifactId> 
    <version>2.0.5</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.0.5</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.module</groupId> 
    <artifactId>jackson-module-jaxb-annotations</artifactId> 
    <version>2.0.5</version> 
</dependency> 

अद्यतन/समाधान

मेरे संदर्भ को डीबग करके मैं देख सकता था कि <mvc:annotation-driven> में कॉन्फ़िगरेशन का कोई प्रभाव नहीं पड़ा।

यह पता चला कि MockMcv के साथ मेरा यूनिट परीक्षण हमेशा डिफ़ॉल्ट हैंडलरैप्टर को लोड करता है, इस प्रकार मेरे कस्टम ऑब्जेक्टमैपर को अनदेखा करता है। सुविधा के कारण मैंने केवल जूनिट टेस्ट का उपयोग करके नियंत्रक का परीक्षण किया, क्योंकि यह नियंत्रक को ठीक से दबाता है, मैंने इसे संभावित त्रुटि कारण के रूप में नहीं सोचा था ...

मुझे अभी तक मेरे परीक्षण के लिए कोई फिक्स नहीं मिला, लेकिन जब मैं कर्ल सब कुछ काम करता है का उपयोग कर सेवा बुलाओ!

अद्यतन/अंतिम समाधान

बस मेरे परीक्षण सेटअप के लिए एक समाधान पाया; जब MockMvc (वसंत-परीक्षण-MVC) का उपयोग कर आप कस्टम संदेश-कन्वर्टर्स स्पष्ट उल्लेख करना होगा:

private MockMvc mockMvc; 

@Autowired 
private MappingJackson2HttpMessageConverter jacksonMessageConverter; 

@Autowired 
private RestController restController; 

@Before 
public void initMockMvc(){ 
    mockMvc = MockMvcBuilders.standaloneSetup(restController) 
      .setMessageConverters(jacksonMessageConverter).build(); 
} 

@Test 
public void testRestController() throws Exception{ 
    DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/json/42"); 
    this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk()); 
} 

केवल शेष मुद्दा यह है कि jacksonMessageConverter सीधे autowired नहीं किया जा सकता जब तक निम्नलिखित JIRA हल हो गई है है: https://jira.springsource.org/browse/SPR-9469। तब तक, मैंने अपने परीक्षण संदर्भ में जैक्सन मैसेज कनवर्टर की एक प्रति बनाई है।

उत्तर

3

मैंने आपकी कॉन्फ़िगरेशन दोहराई और यह मेरे लिए पूरी तरह से काम करता है। डिफ़ॉल्ट संदेश कन्वर्टर्स प्रभावी नहीं होना चाहिए, क्योंकि आपने स्पष्ट रूप से register-defaults=false विशेषता निर्दिष्ट की है। इस प्रकार मेरी @XmlTransient एनोटेशन दिखता है:

@XmlAccessorType(XmlAccessType.FIELD) 
public class EntityWithJAXB { 


    @XmlTransient 
    private EntityWithJAXB aChild; 
+0

धन्यवाद, यह मूल्यवान जानकारी है! मेरे @ एक्सएमएल एनोटेशन इसके बजाय गेटर्स और सेटर्स पर हैं, लेकिन मुझे नहीं लगता कि इससे कोई फर्क पड़ता है। यह मेरी कॉन्फ़िगरेशन में अन्य चीजें हो सकती है जो चीजों को गड़बड़ कर देती है ... मैं जैक्सन कॉन्फ़िगरेशन को एक स्वच्छ प्रोजेक्ट में ले जाने की कोशिश करूंगा ताकि यह देखने के लिए कि यह मेरे लिए काम करता है या नहीं। जब मुझे लगता है तो मैं समाधान पोस्ट करूंगा। – molholm

+1

मैंने कॉन्फ़िगरेशन को एक स्वच्छ प्रोजेक्ट में बनाया है जैसा आपने किया था, कोई समस्या नहीं।मुझे संदेह था कि यह समस्या किसी WebServiceMessageReceiverHandlerAdapter के कारण हुई थी जो प्रेषण-सर्वलेट को डिफ़ॉल्ट एडाप्टर या किसी अन्य कॉन्फ़िगरेशन समस्या को लोड नहीं करता है, लेकिन ऐसा नहीं था। – molholm

+0

मैं समाधान के साथ मूल पोस्ट अद्यतन, धन्यवाद! – molholm