[Spring] web.xml 기본 설정

2020. 6. 10. 17:22 Spring Framework/Spring Core

web.xml 기본 설정


1. 특정 xml 환경 파일 바라보기

DispatherServlet은 클라이언트의 요청을 전달받는 서블릿으로서, 컨트롤러나 뷰와 같은 스프링 MVC의 구성 요소를 이용하여 클라이언트에게 서비스를 제공하게 된다.

DispatherServlet의 설정은 웹 어플리케이션의 /WEB-INF/web.xml 파일에 추가하며, 다음과 같이 서블릿과 매핑 정보를 추가하면 DispatherServlet 설정이 완료된다.


web.xml 파일은 J2EE 웹 어플리케이션의 기본이 되는 설정 파일이다. DispatcherServlet 클래스를 서블릿으로 정의하며 context root 아래에 확장자 .html 파일로 요청을 하면 모두

DispatcherServlet 클래스로 랩핑하도록 정의하고 있다. 이 정의에 의해 .html의 확장자가 붙은 파일로의 액세스는 모두 DispatcherServlet로 송신된다.

DispatcherServlet 클래스에는 <servlet-name> 태그에 의해 ‘shopping-1’ 이라고 서블릿 이름을 지정하여 정의하고 있다.

이 서블릿 이름 ‘shopping-1’ 에 ‘-servlet.XML’ 라는 문자열을 부가함으로써 컨테이너 상에 로드된 스프링 설정 파일명이 결정된다. 예제의 경우 shopping-1-servlet.xml ([서블릿이름]-servlet.xml) 파일이 로드되게 된다.

<servlet>

<servlet-name>shopping-1</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>shopping-1</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>


2. ContextLoaderListener 로드 원리

DispatcherServlet 클래스를 정의하고 context root 이하로의 액세스에 대해서 DispatcherServlet을 맵핑하고 있다. 

다만, 앞 장의 예제와 달리 비즈니스 로직용의 스프링 설정 파일 (applicationContext.xml)을 작성했기 때문에 listener로 ContextLoaderListener 클래스를 정의하고 있다.

ContextLoaderListener 클래스는 스프링 설정 파일(디폴트에서 파일명 applicationContext.xml)을 로드하면 ServletContextListener 인터페이스를 구현하고 있기 때문에 ServletContext 인스턴스 생성 시(톰켓으로 어플리케이션이 로드된 때)에 호출된다. 즉, ContextLoaderListener 클래스는 DispatcherServlet 클래스의 로드보다 먼저 동작하여 비즈니스 로직층을 정의한 스프링 설정 파일을 로드한다.

<listener>

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

</listener>


<servlet>

<servlet-name>shopping-1</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>shopping-1</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>


※ 설정 파일의 로드 순서

여러 개의 설정 파일을 이용할 경우 설정 파일의 참조 관계가 걸리기 때문에 따일의 로드 순서가 중요하다. 

위의 예제에서 사용하는 스프링 MVC의 설정 파일(shopping-1-servlet.xml)에서도 applicationContext.xml 파일로 정의된 인스턴스를 참조하고 있다.

그 때문에 shopping-1-servlet.xml 파일이 로드되기 전에 applicationContext.xml 파일이 로드되어 있어야한다.


cp.) ContextLoaderListener를 이용한 설정

일반적으로 빈 설정 파일은 하나의 파일만 사용되기 보다는 persistance, service, web등 layer 단위로 나뉘게 된다.

또한, 같은 persistance, service layer의 빈을 2개 이상의 DispatcherServlet이 공통으로 사용할 경우도 있다.

이럴때는 공통빈(persistance, service)설정 정보는 ApplicationContext에, web layer의 빈들은 WebApplicationContext에 저장하는 아래와 같은 방법을 추천한다.

공통빈 설정 파일은 서블릿 리스너로 등록된 org.springframework.web.context.ContextLoaderListener로 로딩해서 ApplicationContext을 만들고, web layer의 빈설정 파일은 DispatcherServlet이 로딩해서 WebApplicationContext을 만든다.

<!-- ApplicationContext 빈 설정 파일-->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

                <!--빈 설정 파일들간에 구분은 줄바꿈(\n),컴마(,),세미콜론(;)등으로 한다.-->

                            /WEB-INF/config/easycompany-service.xml,/WEB-INF/config/easycompany-dao.xml 

            </param-value>

</context-param>

<!-- 웹 어플리케이션이 시작되는 시점에 ApplicationContext을 로딩하며, 로딩된 빈정보는 모든 WebApplicationContext들이 참조할 수 있다.-->

<listener>

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

</listener>


<servlet>

<servlet-name>employee</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/config/easycompany-service.xml</param-value>

</init-param>

</servlet>

        

<servlet>

<servlet-name>webservice</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/config/easycompany-webservice.xml</param-value>

</init-param>

</servlet>

이 ApplicationContext의 빈 정보는 모든 WebApplicationContext들이 참조할 수 있다. 

예를 들어, DispatcherServlet은 2개 사용하지만 같은 Service, DAO를 사용하는 web.xml을 아래와 같이 작성했다면, 

easycompany-servlet.xml에 정의된 빈정보는 easycompany-webservice.xml가 참조할 수 없지만, 

easycompany-service.xml, easycompany-dao.xml에 설정된 빈 정보는 easycompany-servlet.xml, easycompany-webservice.xml 둘 다 참조한다. ApplicationContext과 WebApplicationContext과의 관계를 그림으로 나타내면 아래와 같다.




3. 설정 파일 순서 정하기

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

version="2.5">


<listener>

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

</listener>


<servlet>

<servlet-name>shopping3-2</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>


<servlet-mapping>

<servlet-name>shopping3-2</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

</web-app>

web.xml은 DispatherServlet 클래스를 정의하고, 컨텍스트 루트 이하로 들어오는 접근에 대해 DispatherServlet을 맵핑한다. 그리고 리스너로 ContextLoaderLister 클래스를 정의한다.

설정 파일을 복수로 사용할 때에는, 설정 파일을 읽는 순서가 중요하다. 설정 파일 A에서 참조하는 bean을 다른 설정 파일 B에 정의하고 있는 경우, A보다 먼저 B를 읽지 않으면 오류가 일어난다.

샘플에서 사용하는 설정 파일은 shopping3-2-server.xml과 applicationContext.xml 2가지인데, shopping3-2-server.xml에서 applicationContext.xml에 정의된 bean을 이용한다.

이런 이유로 applicationContext.xml 다음에 shopping3-1-server.xml 순서로 설정 파일을 읽는다.


web.xml에서 사용하는 org.springframework.web.context.ContextLoaderListener 클래스는 javax.servlet.ServletContextListener 인터페이스를 구현하는 클래스이다.

ContextLoaderListener 클래스의 기본은 applicationContext.xml이지만 변경도 가능하다. 샘플에서는 비즈니스 로직 계층용으로 설정 파일 'applicationContext.xml'을 만들고, ContextLoaderListner 클래스를 이용해서 읽는다. ContextLoaderListner 클래스는 ServletContext 인스턴스 생성 시(Tomcat 이 애플리케이션을 읽을 때) 호출되는 것으로, DispatherServlet 클래스가 읽기 전 ContextLoaderListener 클래스가 비즈니스 로직 계층용 설정 파일 'applicationContext.xml'을 읽는다.


4. 한 개 이상의 설정파일 설정하기

경우에 따라 한 개 이상의 설정 파일을 사용해야 하는 경우가 있다. 또는 기본 설정 파일 이름이 아닌 다른 이름의 설정 파일을 사용하고 싶은 경우도 있을 것이다.

(빈 설정 파일을 하나 이상을 사용하거나, 파일 이름과 경로를 직접 지정해주고 싶다면 contextConfigLocation 라는 초기화 파라미터 값에 빈 설정 파일 경로를 설정해준다.)

이런 경우, 다음과 같이 DispatherServlet을 설정할 때 contextConfigLocation 초기화 파라미터에 설정 파일 목록을 지정하면 된다.

 <servlet>

         <servlet-name>dispather</servlet-name>

         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfiguration</param-value>

<param-value>

/WEB-INF/main.xml

/WEB-INF/dds.xml

</param-value>

</init-param>

</servlet>

contextConfigLocation 초기화 파라미터는 설정 파일 목록을 값으로 갖는데, 이때 각 설정 파일은 콤마(","), 공백 문자(""), 탭(\t), 줄 바꿈(\n), 세미클론(":")을 이용하여 구분한다.

각 설정 파일의 경로는 웹 어플리케이션 루트 디렉터리를 기준으로 한다.


cp.) 또다른 방법

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/security.xml 

/WEB-INF/applicationContext.xml

</param-value>

</context-param>


<servlet>

<servlet-name>shopping3-7</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>


<servlet-mapping>

<servlet-name>shopping3-7</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

설정 파일이 applicationContext.xml 뿐만 아니라 security.xml도 있다. 복수의 설정 파일을 스프링에 읽게 할 때는 'contextConfigLocation'이라는 파라미터 이름으로, 값에 설정 파일 경로를 지정한다.

복수의 파일을 스페이스로 구획한다.(콤마로 구획 가능)


5. 인코딩 필터 배치하기

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

version="2.5">

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

<init-param>

<param-name>forceEncoding</param-name>

<param-value>true</param-value>

</init-param>

</filter>


<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>


<listener>

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

</listener>


<servlet>

<servlet-name>shopping3-3</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>


<servlet-mapping>

<servlet-name>shopping3-3</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

</web-app>


6. 전체적인 나열 보기

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

version="2.5">

<!-- 필터 설정 -->

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

<init-param>

<param-name>forceEncoding</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- 리스너 설정 -->

<listener>

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

</listener>


<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/security.xml /WEB-INF/applicationContext.xml</param-value>

</context-param>


<!-- DispathcherSerlvet 설정 -->

<servlet>

<servlet-name>shopping3-7</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>shopping3-7</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>


<!-- <filter-mapping> 요소에서의 'springSecurityFilterChain'은 'org.springframework.web.filter.DelegatingFilterProxy'에 붙인 필터 이름이다. 

DelegatingFilterProxy 클래스는 스프링이 제공하는 필터이고, 실제 처리를 필터 이름에 일치하는 이름의 Bean에 위임한다. 

스프링 시큐리티는 'springSecurityFilterChain'이라는 이름으로 스프링에 Bean을 등록하기 때문에 이렇게 필터를 정의하면 스프링 시큐리티 기능이 유효해 진다. 

또한 애플리케이션의 모든 URL에 대해 이 필터 체인을 유효하게 하고, 스프링 시큐리티를 작동시킨다.-->

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>


<!-- 이중 로그인을 막기 위한 리스너 클래스이다.-->

<listener>

<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

</listener>


<!-- error 페이지 설정 -->

<error-page>

<error-code>403</error-code>

<location>/WEB-INF/jsp/noAuthority.jsp</location>

</error-page>

</web-app>



출처: https://devbox.tistory.com/entry/Spring-webxml-기본-설정?category=574587 [장인개발자를 꿈꾸는 :: 기록하는 공간]

'Spring Framework > Spring Core' 카테고리의 다른 글

[Spring] 어노테이션 기반 설정  (0) 2020.07.01
[Spring] 외부 설정 프로퍼티  (0) 2020.07.01
[Spring] iBatis 2  (0) 2020.07.01
[Spring] iBatis 1  (0) 2020.06.10
[spring] 스프링 MVC 인터페이스 구현 클래스  (0) 2020.06.10
[Spring] 스프링 MVC 패턴 개요  (0) 2020.06.10
[Spring] AOP 용어 설명  (0) 2020.06.10
[Spring] 의존관계 주입  (0) 2020.06.10