평소에 궁금했었는데 찾아보지 못한 내용이 있었는데 바로 Legacy Spring에서 DispatcherServlet의 url mapping이 왜 "/*"가 아니라 "/"일까이다.
DispatcherServlet의 urlmapping
url mapping 방식
전통적으로 web.xml의 URL mapping에서 wildcard은 크게 3가지 형태로 사용된다.
형태 |
의미 |
/* |
경로 기반의 매핑 ex) /abc/* -> /abc/ 아래의 모든 요청, : /abc/def, /abc , /abc.do 등 사용 가능 |
*.ext |
확장자 기반 매핑으로 경로에 상관 없이 확장자가 같은 모든 요청 ex)*.do -> 확장자가 do인 모든 요청: /abc.do, /abc/def/ghi.do |
/ |
어떤 URL 매핑에도 연결되지 않았을 때 최후의 수단 ex) / -> /abc/def/ghi.do, /abc 등 모든 요청 |
만약 1번, 2번, 3번이 적용된 servlet이 있다면 1번 url의 servlet이 모든 요청을 다 매핑해서 처리한다.
여기서 1번이 없고 2, 3번만 있다면 확장자가 ext에 해당하는 요청은 2번이, 나머지는 3번이 처리한다. 즉 ext가 do일 때 /abc.do는 2번이 처리하고 /abc는 3번이 처리한다.
마지막으로 1, 2 번이 없고 3번만 있다면 이 녀석도 모든 요청을 다 처리해준다.
그런데 왜 /*가 아닌 / 일까?
/*는 모든 요청을 처리하기는 하지만 막상 servlet에서 getServletPath() 명령으로 요청된 path를 찾아보면 빈 문자열이 반환된다.
This method will return an empty string ("") if the servlet used to process this request was matched using the "/*" pattern.
따라서 /*로 DispatcherServlet을 매핑시켜버리면 어떤 요청인지 알 수 없기 때문에 @Controller의 @RequestMapping에 url을 넘겨줄 수 없는 것이다.!
url 사용 시 주의!
하지만 / 요청은 servlet의 url mapping에 사용된다. 즉 filter에는 /형태로 url을 사용하면 동작하지 않는다.