Spring MVC - HandlerMapping을 이용하여 URL과 Controller 연결하기

2010. 8. 29. 22:06plming/Java - Spring

  Spring MVC에서 사용가능한 Controller와 URL의 매핑을 지원하는 HandlerMapping 또한 여러가지 방법을 가지고 있다.


1. BeanNameUrlHandlerMapping
   BeanNameUrlHandlerMapping은 빈 이름과 URL을 Mapping한다.  Mapping을 연결하는 방법은 Struts 프레임워크와 같은 방법이지만, 다른 점이라면 매핑을 위한 경로정보로 ANT 빌드툴에서 경로정보를 표현하기 위하여 사용하고 있는 스타일을 사용할 수 있다는 것이다.  예를 들어 ANT 빌드툴에서 별표(*), 물음표(?)와 같은 기호들을 사용할 수 있는 것이다.

 <bean name="/**/*.html" class="net.javajigi.common.web.MyUrlFilenameViewController"/>


빈 설정파일에 HandlerMapping이 설정되어 있지 않을 경우 Spring MVC는 BeanNameUrlHandlerMapping을 디폴트 HandlerMapping으로 설정한다.


2. SimpleUrlHandlerMapping
   SimpleUrlHandlerMapping은 매핑에 대한 정보를 각각의 Controller에서 설정하는 것이 아니라 하나의 저장소에서 관리하는 것이다.  Controller를 개발하는 개발자들은 빈을 정의하기만하고 이 Controller가 어떻게 매핑되어서 사용되는지에 대해서는 몰라도 된다.

 action-servlet.xml : SimpleUrlHandlerMapping을 HandlerMapping으로 사용할 경우

 <bean id="staticViewController" class="net.javajigi.common.web.MyUrlFilenameViewController" />

 <bean id="userController" class="net.javajigi.user.web.UserController">
     <property name="methodNameResolver">
         <ref local="userControllerMethodNameResolver" />
     </property>
 </bean>

 <bean id="userControllerMethodNameResolver"
         class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
     <property name="mappings">
         <props>
             <prop key="/user/listUser.do">list</prop>
             <prop key="/user/viewUser.do">view</prop>
         </props>
     </property>
 </bean>


 <bean id="boardController" class="net.javajigi.board.web.BoardController">
     <property name="boardService" ref="boardService" />
     <property name="methodNameResolver" ref="methodNameResolver" />
 </bean>

 <bean id="methodNameResolver"
         class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
     <property name="paramName">
         <value>method</value>
     </property>
     <property name="defaultMethodName">
         <value>list</value>
     </property>
 </bean>


 <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">
         <props>
             <prop key="**/*.html">staticViewController</prop>

             <prop key="/user/listUser.do">userController</prop>
             <prop key="/user/viewUser.do">userController</prop>

             <prop key="/board/board.do">boardController</prop>
         </props>
     </property>
 </bean>


위의 예제에서 Controller는 일반적인 빈을 정의할 때와 별반 다를 것이 없으며, 매핑에 대한 모든 정보는 별도의 빈에서 관리하고 있는 것을 확인할 수 있다("urlMapping").

"urlMapping" 빈에서 Controller와 URL을 매핑하기 위하여 <props/> 태그를 사용하고 있는 것을 알 수 있다.  이는 빈 설정파일에서 <props/>태그를 사용하지 않고 별도의 Properties파일에서 매핑 정보를 관리할 수 있다는 것이다.

SimpleUrlHandlerMapping을 사용할 경우 매핑 정보를 빈 설정파일이 아닌 별도의 파일에서 관리하는 것이 가능해진다.

 action-servlet.xml : 매핑 정보를 URLMap.properties파일에서 관리하는 경우

 <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">
         <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
             <property name="location">
                 <value>/WEB-INF/URLMap.properties</value>
             </property>
         </bean>
     </property>
 </bean>


 URLMap.properties

 **/*.html=staticViewController

 ## user module mapping
 /user/listUser.do=userController
 /user/viewUser.do=userController

 ## board module mapping
 /board/board.do=boardController

SimpleUrlHandlerMapping의 경우 Controller빈을 정의하고 매핑을 별도로 설정하는 불편함이 있다.  하지만 애플리케이션의 규모가 클 경우 매핑 정보를 수정할 필요가 있을 때 BeanNameUrlHandlerMapping보다 더 효율적으로 관리하는 것이 가능하다.  개발하는 입장에서는 SimpleUrlHandlerMapping을 사용한 매핑 방법이 더 불편할 수도 있겠지만 관리하는 입장에서는 SimpleUrlHandlerMapping을 사용하는 것이 더 좋은 선택일 것이다.

BeanNameUrlHandlerMapping과 SimpleUrlHandlerMapping에 대한 사용방법은 현재 진행하고 있는 프로젝트가 어느 부분에 중점을 두고 있느냐에 따라 결정하면 된다.


3. CommonsPathMapHandlerMapping
   CommonsPathMapHandlerMapping은 매핑에 대한 정보를 Controller 클래스에 메타데이터를 추가하여 구현하는 것이 가능하도록 지원한다.

CommonsPathMapHandlerMapping 방법은 JDK 5.0에서 등장한 Annotation과 비슷한 방법을 지원하지만 별도의 컴파일 과정을 거처야 함으로서 진정한 Annotation 역할을 하지는 못하고 있는 상태이다.


4. 하나의 이상의 HandlerMapping을 사용하고자 한다면
   애플리케이션을 개발하다보면 HandlerMapping을 BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping 모두 사용해야하는 경우가 발생할 수 있다.  Spring MVC는 이와 같은 필요성을 지원하기 위하여 org.springframework.core.Ordered 인터페이스를 지원하고 있다.

Spring MVC는 HandlerMapping과 같이 같은 기능을 구현하기 위한 다양한 옵션을 제공하는 기능들이 많다. 그런데 이 같은 옵션들을 하나의 ApplicationContext내에서 같이 사용하고자할 때 각 옵션에 우선 순위를 결정하는 것이 가능하다. Spring 프레임워크는 org.springframework.core.Ordered 인터페이스를 구현함으로서 이 같은 기능이 가능하도록 지원하고 있다.

  Spring 프레임워크의 API에서 org.springframework.core.Ordered 인터페이스를 찾아보면 이 인터페이스를 구현하고 있는 클래스들이 상당히 많다는 것을 알 수 있다. Spring 프레임워크에서는 Spring MVC 뿐만 아니라 다른 영역에서도 하나의 기능에 대해서 다양한 옵션을 지원하는 곳이 많기 때문에 Ordered 인터페이스를 두어서 각각에 대한 우선순위를 결정할 수 있도록 지원하고 있다.


BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping을 같이 사용하도록 빈 설정파일을 변경하면 다음과 같다.

 action-servlet.xml - BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping을 모두 사용하는 경우

 <bean name="/**/*.html" class="net.javajigi.common.web.MyUrlFilenameViewController" />

 <bean name="/user/listUser.do /user/viewUser.do" class="net.javajigi.user.web.UserController">
     <property name="methodNameResolver">
         <ref local="userControllerMethodNameResolver" />
     </property>
     <property name="userService" ref="userService" />
 </bean>

 <bean id="userControllerMethodNameResolver"
 class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
     <property name="mappings">
         <props>
             <prop key="/user/listUser.do">list</prop>
             <prop key="/user/viewUser.do">view</prop>
         </props>
     </property>
 </bean>

 <bean id="boardController" class="net.javajigi.board.web.BoardController">
     <property name="boardService" ref="boardService" />
     <property name="methodNameResolver" ref="methodNameResolver" />
 </bean>

 <bean id="methodNameResolver"
 class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
     <property name="paramName">
         <value>method</value>
     </property>
     <property name="defaultMethodName">
         <value>list</value>
     </property>
 </bean>

 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
     <property name="order"><value>1</value></property>
 </bean>

 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="order"><value>2</value></property>
     <property name="mappings">
         <props>
             <prop key="/board/board.do">boardController</prop>
         </props>
     </property>
 </bean>



[출처] http://www.javajigi.net/pages/viewpage.action?pageId=28377093
[출처] Spring 프레임워크 워크북