[SPRING] 하나의 web.xml에 다중 저지 서블릿
SPRING하나의 web.xml에 다중 저지 서블릿
하나의 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과 컨텍스트 -v2는 별도로로드해야합니까? 그들에는 동일한 이름이있는 콩이 있기 때문에.
편집하다:
내 콘솔 출력을 보면 각 서블릿에 대해 리소스 (admin / info)가 두 번로드됩니다.
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'
해결법
-
==============================
1.예, 두 개 이상의 서블릿을 web.xml에 지정할 수 있습니다. 각각에 대해 다른 서블릿 매핑을 지정하는 것을 잊지 마십시오.
예, 두 개 이상의 서블릿을 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).
-
==============================
2.Jersey와 Spring을 함께 사용하면 Jersey / Spring 서블릿은 사용 가능한 모든 Spring Bean을 탐색하고 그 중에서 찾을 수있는 모든 리소스와 공급자 클래스를 등록합니다.
Jersey와 Spring을 함께 사용하면 Jersey / Spring 서블릿은 사용 가능한 모든 Spring Bean을 탐색하고 그 중에서 찾을 수있는 모든 리소스와 공급자 클래스를 등록합니다.
동일한 (루트) 컨텍스트를 사용하여 여러 개의 Jersey / Spring 서블릿을 만들고 Bean 정의를 공유하는 경우 해당 서블릿에 대해 프로 시저가 수행되고 리소스 및 공급자 클래스가 여러 번 등록됩니다.
같은 bean을 여러 번 등록하지 않으려면 해당 Jersey / Spring 서블릿의 하위 컨텍스트에서 그러한 bean을 정의하십시오.
Spring 관리 클래스와 Jersey 관리 클래스가 혼합되어 있지 않으면 web.xml에서 클래스 선언을위한 초기화 매개 변수를 제공 할 필요가 없습니다.
<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> ...
-
==============================
3.나는이 주제가 대답하기에는 오래되었다는 것을 알고있다. 하지만 내 대답은 다른 사람들을 도울 수 있습니다.
나는이 주제가 대답하기에는 오래되었다는 것을 알고있다. 하지만 내 대답은 다른 사람들을 도울 수 있습니다.
web.xml에 다음과 같은 구분 기호로 여러 리소스 패키지를 구성 할 수 있습니다.
예 :
<?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>
-
==============================
4.한 가지 더 가능한 방법은 com.sun.jersey.spi.spring.container.servlet.SpringServlet의 한 메서드를 재정의하는 것입니다. 초기화 메소드는 다음과 같습니다 (버전 1.19.1).
한 가지 더 가능한 방법은 com.sun.jersey.spi.spring.container.servlet.SpringServlet의 한 메서드를 재정의하는 것입니다. 초기화 메소드는 다음과 같습니다 (버전 1.19.1).
@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; } }
이와 같이 하위 클래스의 코드를 변경하면 기준 (예 : 패키지 이름)을 기반으로 원치 않는 스프링 빈을 필터링 할 수 있습니다.
@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; } }
조금 해키 한 해결책이지만 우리를 위해 완벽하게 작동합니다.
from https://stackoverflow.com/questions/11460977/multiple-jersey-servlets-in-one-single-web-xml by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring RestTemplate 클라이언트 - 연결이 거부 된 예외 (0) | 2019.04.05 |
---|---|
[SPRING] Spring 빈을 ExecutorService의 ThreadLocal 인스턴스처럼 동작하게 만들기 (0) | 2019.04.05 |
[SPRING] 스프링 데이터 jpa를 사용하여 jsonb 열을 쿼리하려면 어떻게합니까? (0) | 2019.04.05 |
[SPRING] thymeleaf spring framework (maven 사용)의 로컬 디렉토리에서 이미지 삽입 (0) | 2019.04.05 |
[SPRING] thread 안전에 관한 혼란 - SimpleDateFormat의 예 (0) | 2019.04.05 |