2012-07-12 11 views
9

में एकाधिक जर्सी सर्वलेट्स एक एकल web.xml में एकाधिक जर्सी सर्वलेट्स रखना संभव है? मैं इस तरह से RESTfull संस्करण करने के लिए कोशिश कर रहा हूँ:एक ही वेब.एक्सएमएल

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 

    <display-name>myapi</display-name> 

    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/context-v1.xml /WEB-INF/context-v2.xml</param-value> 
    </context-param> 

    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
    <servlet-name>REST-V1</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>com.myapi.rest.v1</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
    <servlet-name>REST-V1</servlet-name> 
    <url-pattern>/v1/*</url-pattern> 
    </servlet-mapping> 

    <servlet> 
    <servlet-name>REST-V2</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>com.myapi.rest.v2</param-value> 
    </init-param> 
    <load-on-startup>2</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
    <servlet-name>REST-V2</servlet-name> 
    <url-pattern>/v2/*</url-pattern> 
    </servlet-mapping> 

    <welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
    </welcome-file-list> 

</web-app> 

लेकिन वसंत संदर्भ v1 और संदर्भ-वी 2 अलग लोड किया जाना चाहिए? वे सेम, जो एक ही नाम आदि है क्योंकि

संपादित करें:

आप मेरे कंसोल आउटपुट यह प्रत्येक सर्वलेट के लिए संसाधनों (व्यवस्थापक/जानकारी) दो बार लोड हो रहा है में देखें, तो:

15.07.2012 14:47:08 com.sun.jersey.api.core.PackagesResourceConfig init 
INFO: Scanning for root resource and provider classes in the packages: 
    com.myapi.rest.v1 
15.07.2012 14:47:08 com.sun.jersey.api.core.ScanningResourceConfig logClasses 
INFO: Root resource classes found: 
    class com.myapi.rest.v1.LOAdminResource 
    class com.myapi.rest.v1.LOInfoResource 
15.07.2012 14:47:08 com.sun.jersey.api.core.ScanningResourceConfig init 
INFO: No provider classes found. 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext 
INFO: Using default applicationContext 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, adminResource_v2, of type com.myapi.rest.v2.LOAdminResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, infoResource_v2, of type com.myapi.rest.v2.LOInfoResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, adminResource_v1, of type com.myapi.rest.v1.LOAdminResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, infoResource_v1, of type com.myapi.rest.v1.LOInfoResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate 
INFO: Initiating Jersey application, version 'Jersey: 1.8 06/24/2011 12:17 PM' 
15.07.2012 14:47:09 com.sun.jersey.api.core.PackagesResourceConfig init 
INFO: Scanning for root resource and provider classes in the packages: 
    com.myapi.rest.v2 
15.07.2012 14:47:09 com.sun.jersey.api.core.ScanningResourceConfig logClasses 
INFO: Root resource classes found: 
    class com.myapi.rest.v2.LOAdminResource 
    class com.myapi.rest.v2.LOInfoResource 
15.07.2012 14:47:09 com.sun.jersey.api.core.ScanningResourceConfig init 
INFO: No provider classes found. 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext 
INFO: Using default applicationContext 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, adminResource_v2, of type com.myapi.rest.v2.LOAdminResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, infoResource_v2, of type com.myapi.rest.v2.LOInfoResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, adminResource_v1, of type com.myapi.rest.v1.LOAdminResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans 
INFO: Registering Spring bean, infoResource_v1, of type com.myapi.rest.v1.LOInfoResource as a root resource class 
15.07.2012 14:47:09 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate 
INFO: Initiating Jersey application, version 'Jersey: 1.8 06/24/2011 12:17 PM' 
+0

लोड-ऑन-स्टार्टअप चाहिए - अगर मुझे सही याद है - –

+0

नहीं, दोनों मामलों में 1 हो, यह सच नहीं है, यह servlets का बूट अनुक्रम है ... – Ben

उत्तर

9

हां आप web.xml में दो या दो से अधिक सर्वलेट निर्दिष्ट कर सकते हैं। प्रत्येक के लिए एक अलग सर्वलेट मैपिंग निर्दिष्ट करना याद रखें।

<servlet> 
    <servlet-name>servletOne</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
    <param-name>com.sun.jersey.config.property.packages</param-name> 
    <param-value>com.packageOne</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet> 
    <servlet-name>servletTwo</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
    <param-name>com.sun.jersey.config.property.packages</param-name> 
    <param-value>com.packageTwo</param-value> 
    </init-param> 
    <load-on-startup>2</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>ServletOne</servlet-name> 
    <url-pattern>/v1/*</url-pattern> 
</servlet-mapping> 
    <servlet-mapping> 
    <servlet-name>ServletTwo</servlet-name> 
<url-pattern>/v2/*</url-pattern> 
</servlet-mapping> 

initParameter loadOnStartup जिसमें सर्वलेट लोड किए गए हैं क्रम (इस मामले पहले servletOne और फिर servletTwo में) को परिभाषित करता है।

+0

यह सच है, दोनों servlets लोड हो रहे हैं .. लेकिन एक ले लो मेरे कंसोल आउटपुट को देखो। मेरी समस्या यह है कि मेरे संसाधन (AdminResource, InfoResource) प्रत्येक सर्वलेट के लिए दो बार लोड किए जाते हैं ... – Ben

+0

mmm ... अजीब है क्योंकि आपने दो अलग-अलग पैकेजों को परिभाषित किया है ... वैकल्पिक रूप से आप सर्वर और सर्वलेट को परिभाषित करने का प्रयास कर सकते हैं प्रोग्रामेटिक रूप से (जैसा कि यहां परिभाषित कोड http://stackoverflow.com/questions/11210734/jersey-on-jetty-on-android-throws-containerexception-the-resourceconfig-instanc प्रारंभ सर्वर एंड्रॉइड गतिविधि के तहत) – Giorgio

+0

यह सही नहीं है का जवाब! स्प्रिंग प्रत्येक एनोटेटेड क्लास को मुख्य संदर्भ में पायेगी, इससे कोई फर्क नहीं पड़ता कि आपने यहां क्या रखा है। तो आपके पास दो सर्लेट होंगे जो सटीक सामान की सेवा करेंगे। सावधान रहें और कोशिश करो! सही उत्तर ऊपर है ... – markthegrea

6

बात यह है कि जब आप जर्सी और वसंत का एक साथ उपयोग करते हैं, तो जर्सी/स्प्रिंग सर्वलेट सभी उपलब्ध वसंत बीन्स के माध्यम से जाता है और प्रत्येक संसाधन और प्रदाता वर्गों को पंजीकृत करता है, यह उनके बीच पाएगा।

यदि आपके पास एक ही (रूट) संदर्भ का उपयोग करके एकाधिक जर्सी/स्प्रिंग सर्वलेट हैं और इस प्रकार बीन परिभाषाओं को साझा करते हैं, तो प्रक्रिया प्रत्येक ऐसे सर्वलेट और संसाधन और प्रदाता कक्षा के लिए कई बार पंजीकृत होती है।

एक ही बीन के एकाधिक पंजीकरण से बचने के लिए, संबंधित जेसरी/स्प्रिंग सर्वलेट के बाल संदर्भ में ऐसे बीन्स को परिभाषित करें।

वेब.एक्सएमएल में कक्षाओं की घोषणा के लिए प्रारंभिक मानदंड प्रदान करना भी आवश्यक नहीं है जब तक कि स्प्रिंग-प्रबंधित और जर्सी-प्रबंधित वर्गों का मिश्रण आवश्यक न हो।

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/root-context.xml</param-value> 
</context-param> 

... 

<servlet> 
    <servlet-name>REST-V1</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/context-v1.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet> 
    <servlet-name>REST-V2</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/context-v1.xml /WEB-INF/context-v2.xml</param-value> 
    </init-param> 
    <load-on-startup>2</load-on-startup> 
</servlet> 

... 
+0

यह चयनित उत्तर होना चाहिए। – manikanta

1

मुझे पता है कि यह विषय उत्तर देने के लिए पुराना है। लेकिन मेरा जवाब दूसरों की मदद कर सकता है।

हम इन सीमांकक के साथ web.xml में कई संसाधन संकुल कॉन्फ़िगर कर सकते हैं:

  1. व्हाइट अंतरिक्ष
  2. अल्पविराम (,)
  3. अर्द्धविराम (;)
  4. Nextline

उदाहरण:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 
    <display-name>MultiplePackageRest</display-name> 
    <servlet> 
    <servlet-name>JerseyMultiplePackage</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>jersey.config.server.provider.packages</param-name> 
     <param-value>info.javadoff.rest1,info.javadoff.rest2,...</param-value> 
    </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>JerseyMultiplePackage</servlet-name> 
    <url-pattern>/api/*</url-pattern> 
    </servlet-mapping> 
</web-app> 
1

com.sun.jersey.spi.spring.container.servlet.SpringServlet में एक विधि को ओवरराइड करना एक और संभावना है। आरंभिक विधि इस तरह दिखती है (संस्करण 1.1 9।1):

@Override 
protected void initiate(ResourceConfig rc, WebApplication wa) { 
    try { 
     SpringComponentProviderFactory springComponentProviderFactory = new SpringComponentProviderFactory(rc, getContext()); 
     rc.getClasses().removeIf(clazz -> clazz.getPackage().getName().startsWith("bla")); 
     wa.initiate(rc, springComponentProviderFactory); 
    } catch (RuntimeException e) { 
     LOGGER.log(Level.SEVERE, "Exception occurred when intialization", e); 
     throw e; 
    } 
} 

यह है कि:

@Override 
protected void initiate(ResourceConfig rc, WebApplication wa) { 
    try { 
     wa.initiate(rc, new SpringComponentProviderFactory(rc, getContext())); 
    } catch (RuntimeException e) { 
     LOGGER.log(Level.SEVERE, "Exception occurred when intialization", e); 
     throw e; 
    } 
} 

आप इस तरह एक उपवर्ग में कोड को बदलते हैं, तो आप बाहर अवांछित वसंत सेम आपके मानदंड (उदाहरण के पैकेज का नाम के लिए) के आधार पर फ़िल्टर कर सकते हैं हैकी समाधान, लेकिन हमारे लिए पूरी तरह से काम करता है।

संबंधित मुद्दे