action-servlet.xml 작성

Spring MVC의 DispatcherServlet은 WebApplicationContext를 가지고 있고 context Hierarchy는 다음 그림과 같다.
또한 WebApplicationContext에 설정할 수 있는 특별한 bean들은 다음과 같다.
Bean type
설명
Controllers 각종 컨트롤러들
Handler mappings 요청된 URL을 처리할 컨트롤러와 매칭
View resolvers View를 결정
Locale resolver 국제화 지원하기 위해 사용자의 locale 알아냄
Theme resolver 테마 사용할 때 사용
Multipart file resolver 폼에서 파일 업로드 할 때 사용
Handler exception resolver 특정 예외가 발생할 때의 보여줄 view 등록
이러한 bean들을 action-servlet.xml 파일에 정의하여 사용하게 된다.

action-servlet.xml 설정

web.xml 설정이 끝나면 위에서 설명한 WebApplicationContext 요소들을 action-servlet.xml파일에 정의해줘야 한다. 이 페이지에서는 Handler Mapping과 View Resolver를 정의하는 방법에 대해 알아보고 다른 요소(Controller , Locale Resolver , Multipart File Resolver , Exception Resolver )들에 대해서는 각각의 상세 페이지에서 설명하도록 한다.

Handler Mapping

Cotroller와 URL을 매핑하기 위해서 Spring MVC에서는 여러가지의 Handler Mapping을 지원한다. 또한 Handler Mapping에 요청된 URL경로를 입력할 때 /**/*.do 와 같이 "*" 기호를 사용하여 경로를 지정하는것이 가능하다.
  • BeanNameUrlHandlerMapping
  • BeanNameUrlHandlerMapping은 bean 이름과 URL을 Mapping한다. 다음은 BeanNameUrlHandlerMapping을 정의한 common-servlet.xml 파일의 일부이다.
    <bean id="beanNameUrlHandlerMapping"
    	class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    </bean>
    아무런 HandlerMapping도 정의하지 않으면 default로 BeanNameHandlerMapping이 적용된다.
    <bean name="/login.do"
    	class="anyframe.sample.springmvc.web.controller.basic.LoginController">
    </bean>
    위와같이 정의되어 있는 Controller bean이 있다면 "/login.do"라는 요청이 들어왔을 때 class로 정의되어있는 LoginController에서 해당 요청을 처리하게 된다.
  • SimpleUrlHandlerMapping
  • SimpleUrlHandleMapping은 매핑에 대한 정보를 각각의 Controller에서 설정하는 것이 아니라 하나의 저장소에서 관리하는 것이다. 사용자는 컨트롤러를 빈으로 정의해 주고 mappings 프로퍼티의 value값에 각각의 요청에 대한 컨트롤러 매핑만 지정해 주면 된다. 다음은 위의 BeanNameUrlHandlerMapping 예시를 SimpleUrlHandlerMapping을 이용해 나타낸 것이다.
    <bean id="simpleUrlHandlerMapping"
    	class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    	<property name="mappings">
    		<value>
    			/login.do = loginController
    		</value>
    	</property>
    </bean>
    
    <bean id="loginController"
    	class="anyframe.sample.springmvc.web.controller.basic.LoginController">
    </bean>
    또한 SimplerUrlHandlerMapping을 사용할 경우 매핑 정보를 빈 설정 파일이 아닌 별도의 파일에서 관리하는 것이 가능하다. 예는 다음과같다.
    <bean id="simpleUrlHandlerMapping" 
         class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                <property name="location">
                    <value>/mapping.properties</value>
                </property>
            </bean>
        </property>
    </bean>
    다음은 위에서 정의된 mapping.properties파일의 내용이다.
    /login.do = loginController
  • Intercepting requests
  • handler mapping은 interceptor를 만들어 요청이 들어오기 전(preHandle), 들어온 후(postHandle), 완료된 후(afterCompletion)에 특정 작업을 추가할 수 있다. 예를 들어 로그인한 사용자에게만 보여주고 싶은 페이지가 있다면 매번 exception을 발생시켜 페이지를 이동시켜 주지 않아도 페이지 요청 처리 전에 interceptor를 preHandler정의 하면 mappings의 value로 지정되어있는 모든 요청에 대해 interceptor를 적용시킬 수 있다. 이러한 interceptor를 처리하기 위해서는 먼저 interceptor를 만들어 줘야 하는데 이는 HandlerInterceptorAdapter를 extends하여 interceptor를 발생시킬 시점에 따른 메소드를 오버라이딩 한다.

    다음은 interceptor 구현 예인 LoginInterceptor.java 파일의 일부이다.
    public class LoginInterceptor extends HandlerInterceptorAdapter{
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
    		                Object hadler) throws Exception {
    		  if(request.getSession().getAttribute("userId") != null)
    	            return true;
    	        else {
    	            response.sendRedirect("login.jsp");
    	            return false;
    	        }
    	}
    }
    위의 예는 preHandle메소드를 오버라이딩 하여 요청이 들어오기 전에 위와같은 작업을 수행 하게되는것이다. session에 userId값이 존재할 경우 true를 리턴하고 요청을 처리하게 될 것이고, userId값이 존재 하지 않는다면 login.jsp페이지를 출력하게 될것이다. 다음은 빈 설정파일에 interceptor를 설정한 user-servlet.xml 파일의 일부이다.
    <bean id="simpleUrlHandlerMapping"
    	class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    	<property name="mappings">
    		<value>
    			/userForm.do = userController
    		</value>
    	</property>
    	<property name="interceptors" ref="loginInterceptor"/>
    	<!-- 여러개의 handler mapping이 정의되어 있을시에 order를 정의하여 우선순위를 줄 수 있다.
    	 	숫자가 작을수록 높은 우선순위를 갖는다.-->
    	<property name="order">
    		<value>1</value>
    	</property>
    </bean>
    
    <bean id="loginInterceptor" class="anyframe.sample.springmvc.web.interceptor.LoginInterceptor" />
    위와 같은 설정으로 interceptor를 사용해 요청에 따른 interceptor를 정의해줄 수 있다.

View Resolver

핸들러(controller)는 요청을 처리 한 뒤 ModelAndView 객체를 넘겨준다. 이 때 이 객체에 view의 이름을 같이 넘겨 주는데 이 이름으로 실제 view를 찾아 주는 역할을 하는 것이 View Resolver이다.
Spring이 제공하는 View Resolver들은 다음과 같다.
ViewResolver
설명
AbstractCachingViewResolver View 들을 cashing하는 기능 제공
XmlViewResolver ViewResolver 의 구현체로 XML파일 사용(/WEB-INF/views.xml 을 기본 설정파일로 사용)
ResourceBundleViewResolver ViewResolver 의 구현체로 리소스 파일 사용(views.properties 를 기본 리소스 파일로 사용)
UrlBasedViewResolver ViewResolver 의 구현체로 특별한 맵핑 정보 없이 의미상 view 이름을 URL로 사용(View 이름과 실제 view 자원과의 이름이 같을 때 사용)
InternalResourceViewResolver UrlBasedViewResolver 를 상속 받았으며 InternalResourceView(Servlet, JSP)를 사용
VelocityViewResolver/FreeMarkerViewResolver UrlBasedViewResolver 를 상속 받았으며 VelocityView 와 FreeMarkerView를 사용
사용하려는 기술에 따라 위와같은 View Resolver를 적절히 선택해야 한다.

  • JSP 사용
  • <bean id="viewResolver"
          class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    

    viewResolver는 action 요청 처리 후 사용자에게 보여줄 view를 찾는 역할을 하고 prefix와 suffix를 지정해 줄수 있다. 만약 controller에서 넘겨준 modelAndView 값이 index이고 prefix를 "/jsp/", suffix를 ".jsp"라고 정의 했다면 이 viewResolver는 "/jsp/index.jsp"를 찾게 된다. 이러한 viewResolver 정보를 변경함으로써 Velocity, Excel, PDF등을 View로 이용하는 것이 가능하다.

  • JSTL 사용
  • 다음은 JstlView가 설정되어 있는 common-servlet.xml 의 일부이다.
    <bean id="jstlViewResolver"
    	class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    	<!-- view class for jstl -->
    	<property name="viewClass"
    		value="org.springframework.web.servlet.view.JstlView" />
    	<property name="order" value="1" />
    </bean>
    만약 JSTL 태그를 사용한다면 viewClass를 JstlView로 지정해 준다. JstlView도 요청을 JSP에 전달한다.

Resources

  • 다운로드
  • 이클립스 프로젝트 형태의 샘플 웹 어플리케이션을 포함하고 있는 anyframe-springmvc-sample-basic.zip 파일을 다운받은 후, 테스트 환경 설정 을 참조하여 위에서 제시한 예제 코드를 실행해 볼 수 있다.
    Name
    Download
    anyframe-springmvc-sample-basic.zip
    Download

  • 참고자료