본문 바로가기
Dev/Spring

DispatcherServlet - alwaysUseFullPath

by vellahw 2022. 10. 20.

 

 

💡. DispatcherServlet

DispatcherServlet은 DefaultAnnotationHandlerMapping 클래스를 기본 HandlerMapping 구현체로 사용한다.

기본 설정은 컨텍스트 내에서의 전체 경로가 아닌 Servlet 경로를 제외한 나머지 경로에 대해 Mapping을 처리한다.

1
2
3
4
5
6
7
8
9
10
11
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
        
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
    <url-pattern>/game/*</url-pattern>
</servlet-mapping>
cs

DispatcherServlet에 대해서 위와 같이 Servlet Mapping을 설정했다고 했을 때 위 코드는 *.do로 오는 요청과 /game/으로 오는 요청을 dispatcherServlet이 처리하도록 설정하고 있다.

이 경우 @RequestMapping은 다음과 같이 설정 할 수 있는데

1
2
3
4
5
6
7
8
9
@RequestMapping("/search/game.do")
    public String search(..){
            ...
    }
             
@RequestMapping("/game/info")
    public String info(..){
             ...
    }
cs

코드만 보면 /search/game.do에 대한 요청은 search() 메서드가 처리하고 /game/info에 대한 요청은 info() 메서드가 처리한다고 생각하기 쉽다. 하지만, search() 메서드만 /search/game.do에 대한 요청을 처리하고, info() 메서드는 /game/info 요청을 처리하지 않는다.

그 이유는 Servlet Mapping 설정에서 <url-pattern>의 값을 /game/* 로 설정 했기 때문이다.

<url-pattern>의 값으로 디렉터리를 포함한 패턴을 지정하게 되면 Servlet 경로는 "/game"이 되며, Servlet 경로를 제외한 나머지 경로를 이용해서 @RequestMapping Annotation의 값과 매칭 여부를 판단하게 되므로, 실제 비교할 때 사용되는 요청 URI는 "/info"가 된다.
따라서 @RequestMapping Annotation의 값은 "/game/info"이므로 비교할 요청 URI인 "info"와는 매칭되지 않게 된다.

반면에 /search/game.do 요청은 <url-pattern>이 *.do인 확장자 기반의 매칭이 되므로 Servlet 경로가 ""이 된다.

따라서, /search/game.do 요청은 값이 "/search/game.do"인 @RequestMapping Annotation과 매칭된다.

 

 

DispatcherServlet이 기본적으로 사용하는 HandlerMapping 구현체와 HandlerAdapter 구현체가 전체 경로를 사용하지 않도록 설정 되어 있기 때문에 Servlet 경로를 제외한 나머지 경로를 사용하는데,

만약 Servlet 경로를 포함한 전체 경로를 이용해서 매칭 여부를 판단하도록 설정하려면, 스프링 설정 파일에 두 구현체의 alwaysUseFullPath 프로퍼티 값이 true가 되도록 설정해 주어야 한다.

1
2
3
4
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" 
        p:alwaysUseFullPath="true"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
        p:alwaysUseFullPath="true"/>
cs

 

 

 

🎈. alwaysUseFullPath 설정 사용 예제

1) Servlet Mapping 설정

1
2
3
4
5
6
7
8
9
<servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
    <url-pattern>/game/*</url-pattern>
</servlet-mapping>
cs

 

2) 컨트롤러 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package springMVC.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class GameInfoController {
    @RequestMapping("/game/info")
    public String gameInfo() {
        return "game/users/info";
    }
    
    @RequestMapping("/game/list")
    public String gameList() {
        return "game/list";
    }
}
cs

 

3) 스프링 설정 파일 작성

1
2
3
4
5
6
7
<bean class="springMVC.controller.GameInfoController" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="alwaysUseFullPath" value="true" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="alwaysUseFullPath" value="true" />        
</bean>
cs

 

4) 뷰 파일 작성

1
2
3
4
5
6
7
8
9
10
<%@ page contentType="text/html; charset=EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>캐릭터 정보</title>
</head>
<body>
${userId} 회원의 정보 출력
</body>
</html>
cs

 

✨ 실행 결과

댓글