2013-05-26 9 views
11

के साथ जैक्सन ऑब्जेक्टमैपर को कैसे हुक करें मैं अपने जैक्सन ऑब्जेक्ट मैपर मॉड्यूल को सही तरीके से पंजीकृत नहीं कर पा रहा हूं।गिसिस/जर्सी

मैं एक गिइस + जर्सी + जैक्सन (FasterXML) स्टैक का उपयोग कर रहा हूं।

मैंने यहां विभिन्न प्रश्नों के आधार पर ऑब्जेक्टमैपर को कस्टमाइज़ करने का तरीका बताया है। विशेष रूप से, मेरे पास एक ContextResolver घोषित किया गया है, जिसे @ javax.ws.rs.ext.Provider और @ javax.inject.Singleton के रूप में चिह्नित किया गया है।

मैं की तर्ज पर एक GuiceServletContextListener है:

@Override 
protected Injector getInjector() { 

    Injector injector = Guice.createInjector(new DBModule(dataSource), 
      new ServletModule() 
      { 
       @Override 
       protected void configureServlets() { 


        // Mapper 
        bind(JacksonOMP.class).asEagerSingleton(); 

        // ... 

        Map<String, String> initParams = new HashMap<String, String>(); 
        initParams.put("com.sun.jersey.config.feature.Trace", 
          "true"); 
        initParams.put("com.sun.jersey.api.json.POJOMappingFeature", "true"); 

        serve("/services/*").with(
          GuiceContainer.class, 
          initParams); 
       } 
      }); 

    return injector; 
} 

मैपर परिभाषित

import javax.inject.Singleton; 
import javax.ws.rs.Produces; 
import javax.ws.rs.ext.ContextResolver; 
import javax.ws.rs.ext.Provider; 

@Provider 
@Singleton 
@Produces 
public class JacksonOMP implements ContextResolver<ObjectMapper> { 

    @Override 
    public ObjectMapper getContext(Class<?> aClass) { 
    final ObjectMapper mapper = new ObjectMapper(); 
    mapper.registerModule(new Hibernate4Module()); 
    return mapper; 
    } 
} 

हालांकि - अकेले इस विन्यास के साथ, getContext() कभी नहीं कहा जाता है, तो नक्शाकार पंजीकृत कभी नहीं किया गया है। मैं एक ठेठ गुस्से में फंस गया हूं - एनोटेशन-रहस्य, जहां यह वास्तव में जो करने के लिए किया जा रहा है उसके लिए व्यावहारिक रूप से अचूक है। वसंत उपयोगकर्ता सिर्फ घटक को पंजीकृत करने की रिपोर्ट करते हैं, और कंटेनर बस इसे उठाता है।

This उत्तर अपने javax.ws.rs.core.Aplication कार्यान्वयन को ओवरराइड करने के बारे में उत्तर वार्ता। बहरहाल, यह लग रहा है कठिन वायर्ड GuiceContainer की जर्सी-guice impementation में होने की DefaultResourceConfig():

@Override 
protected ResourceConfig getDefaultResourceConfig(Map<String, Object> props, 
     WebConfig webConfig) throws ServletException { 
    return new DefaultResourceConfig(); 
} 

मैं यहाँ उपवर्ग GuiceContainer माना जाता है? या क्या कोई अन्य जादू एनोटेशन है जो मुझे याद आ रही है?

ऐसा करना एक आम बात है जो करना चाहता है - मुझे आश्चर्य है कि यह इस गाइड संयोजन के साथ कितना मुश्किल साबित हो रहा है।

उत्तर

22

मैं एक ठेठ guice में अटक कर रहा हूँ - एनोटेशन-रहस्य है, जहां यह व्यावहारिक रूप से क्या मैं वास्तव में क्या कर रही होना चाहिए कर रहा हूँ करने के लिए अनुसरणीय है। वसंत उपयोगकर्ता सिर्फ घटक को पंजीकृत करने की रिपोर्ट करते हैं, और कंटेनर बस इसे उठाता है।

आपको वास्तव में excellent Guice documentation पढ़ना चाहिए। गुइस का उपयोग करना बहुत आसान है, इसमें बहुत कम बुनियादी अवधारणाएं हैं। आपकी समस्या यह है कि आपने जर्सी जेएक्स-आरएस निर्भरता इंजेक्शन और गिइस निर्भरता इंजेक्शन मिश्रित किया है। यदि आप GuiceContainer का उपयोग कर रहे हैं तो आप घोषणा करते हैं कि आप अपने DI के सभी के लिए Guice का उपयोग करेंगे, इसलिए आपको गुइस के साथ बाइंडिंग जोड़नी होगी, न कि JAX-RS के साथ।

उदाहरण के लिए, आप ContextResolver जरूरत नहीं है, आप सादे Guice Provider बजाय का उपयोग करना चाहिए:

import com.google.inject.Provider; 

public class ObjectMapperProvider implements Provider<ObjectMapper> { 
    @Override 
    public ObjectMapper get() { 
     final ObjectMapper mapper = new ObjectMapper(); 
     mapper.registerModule(new Hibernate4Module()); 
     return mapper; 
    } 
} 

तो फिर तुम इसी अपने मॉड्यूल के लिए बाध्य जोड़ना चाहिए:

bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).in(Singleton.class); 

यह ObjectMapper बाध्य होगा, लेकिन जैक्सन के साथ जर्सी का उपयोग करने के लिए पर्याप्त नहीं है। आपको किसी प्रकार की MessageBodyReader/MessageBodyWriter की आवश्यकता होगी, उदा। JacksonJsonProvider।आप इसके लिए किसी अन्य प्रदाता की आवश्यकता होगी:

public class JacksonJsonProviderProvider implements Provider<JacksonJsonProvider> { 
    private final ObjectMapper mapper; 

    @Inject 
    JacksonJsonProviderProvider(ObjectMapper mapper) { 
     this.mapper = mapper; 
    } 

    @Override 
    public JacksonJsonProvider get() { 
     return new JacksonJsonProvider(mapper); 
    } 
} 

तो यह बाँध:

bind(JacksonJsonProvider.class).toProvider(JacksonJsonProviderProvider.class).in(Singleton.class); 

यह तुम सब करने की जरूरत है - कोई उपवर्गीकरण की जरूरत है।

हालांकि कोड आकार अनुकूलन के लिए एक कमरा है। अगर मैं तुम्हें थे मैं @Provides -methods का प्रयोग करेंगे:

@Provides @Singleton 
ObjectMapper objectMapper() { 
    final ObjectMapper mapper = new ObjectMapper(); 
    mapper.registerModule(new Hibernate4Module()); 
    return mapper; 
} 

@Provides @Singleton 
JacksonJsonProvider jacksonJsonProvider(ObjectMapper mapper) { 
    return new JacksonJsonProvider(mapper); 
} 

इन विधियों अपने मॉड्यूल, उदा में से एक में जोड़ा जाना चाहिए अज्ञात ServletModule पर। फिर आपको अलग प्रदाता कक्षाओं की आवश्यकता नहीं होगी।
बीटीडब्ल्यू, आपको सादे ServletModule के बजाय JerseyServletModule का उपयोग करना चाहिए, यह आपके लिए बहुत उपयोगी बाइंडिंग प्रदान करता है।

+0

यह बहुत उपयोगी है। मेरी विशेष समस्या वास्तव में थी कि मेरे पास * 2 * जैक्सन (कोडहॉस संस्करण और तेज़ एक्सएमएल संस्करण दोनों) थे, इसलिए ऑब्जेक्टमैपर्स को पूरी तरह नजरअंदाज कर दिया गया क्योंकि वे गलत प्रकार के थे। – user340535

+0

मेरे पास समान निर्भरता संघर्ष समस्या थी (कोडहॉस + fastxml): 'जेसन इग्नोर' बिल्कुल काम नहीं कर रहा था। मेरे मामले में, जैक्सन कोडहॉस (जैक्सन-मैपर-एएसएल या कोर-एएसएल) को एज़ूर दस्तावेज़ डीबी पैकेज निर्भरता से जोड़ा गया था और केवल नवीनतम (fastxml) संस्करण को रखने के लिए पूरी तरह से (पोम बहिष्करण द्वारा) हटा दिया गया है। आपकी टिप्पणी के लिए @ user340535 पर धन्यवाद जो मुझे जैक्सन जेसनप्रोवाइडर हुक को ठीक करने में मदद करता है! – boly38

+0

कुछ कारणों से एनर्जी के साथ संस्करण गिसिस 4 में जर्सीगुइस सर्टलेट कॉन्टेक्स्ट लिस्टनर का उपयोग करके मेरे साथ काम नहीं करता है। इसका क्या कारण हो सकता है? सामान्य बाध्यकारी और अतिरिक्त कक्षाओं के साथ यह किसी भी मुद्दे के साथ काम करता है। – Atais