파게로그

[Spring MVC] Spring Dispatcher를 Front Controller로 설정하기 본문

콤퓨타 왕기초/Spring

[Spring MVC] Spring Dispatcher를 Front Controller로 설정하기

파게 2021. 4. 26. 01:19

IndexController extends HttpServlet... 이렇게 컨트롤러를 만들 수도 있지만, 그러한 서블릿의 기능은 Spring DispatcherServlet이 가져가도록 분리할 것이다. 이렇게 분리한 후 Controller는 POJO로 생성한다.

 

 

Front Controller는 모든 URL에 대한 요청을 다 받아야만 한다. 다시 말해서, Front Controller가 매핑해주지 않은 URL은 표시가 되지 않아야 한다. URL mapping을 위해서 기존에는 annotation을 사용했는데, 이제는 소스 코드가 없으므로 annotation을 이용하는 것은 불가능하다. 즉, web.xml을 이용해야 한다.

 

web.xml

  <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>/</url-pattern>
  </servlet-mapping>

 

url pattern을 '/'로 하면 모든 URL이 통과되고, '/*'로 하면...? Tomcat의 web.xml은 그냥 모든 URL을 받아서 Front Controller, 즉 DispatcherServlet에 넘겨주며, URL mapping 정보는 DispatcherServlet이 가진다. 이 URL mapping 정보는 DispatcherServlet의 이름을 dispatcher라고 하면, dispatcher-servlet.xml이다. 파일의 위치나 이름은 자유롭지만, 컨벤션은 WEB-INF 내에 만드는 것이다.

이 XML 파일의 스펙은?

docs.spring.io/spring-framework/docs/

여기서 XML-based configuration metadata를 찾아서 복사 후 붙여넣는다. 한편 Spring MVC에서는 Bean 객체의 id가 URL이다. 그리고 모든 POJO 클래스인 Controller는, dispatcher가 정의해둔 handleRequest 함수를 정의해야한다.

 

IndexController.java

package com.ddoongi.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class IndexController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		ModelAndView mv = new ModelAndView();
		mv.addObject("data", "Hello Spring MVC~");
		mv.setViewName("index.jsp");
		
		return mv;
	}
}

 

참고로 여기서 404 에러가 발생하는 건...

mv.setViewName("index.jsp")에서 에러가 발생한 것이다.

해결 방안을 생각해보면 다음과 같은 과정으로 생각이 흘러간다.

 

1. web.xml에서 URL pattern을 '/*'에서 '/'로 변경한다.

2. 하지만 이는 클라이언트가 Controller가 아닌 View를 바로 요청하는 것을 허용해버린다.

3. index.jsp를 WEB-INF 내부로 이동시켜 숨긴다(WEB-INF는 클라이언트는 접근할 수 없지만 Controller를 포함한 서버측에서는 접근할 수 있다).

4. IndexController.java의 mv.setViewName("index.jsp");는 mv.setViewName("/WEB-INF/view/index.jsp");로 변경한다.

 

dispatcher-servlet.xml

<bean id="/index" class="com.ddoongi.web.controller.IndexController"></bean>

 

절대경로를 사용하지 않고자 mv.setViewName("WEB-INF/view/index.jsp")라고 해서 상대경로를 사용하고자 한다면? dispatcher-servlet.xml에서 Bean 객체의 id를 "/a/index"로 바꾼 상황을 가정해보자. http://.../aa/index 이렇게 되어 있는 상태에서, 밑줄 부분에 상대주소가 적용되어 http://.../aa/WEB-INF/view/index.jsp로 바뀌어버린다. 그냥 dispatcher-servlet.xml의 아이디는 /index로 두고 절대경로 쓰는게 정신건강에 좋다. 상대경로를 쓰는 것은 좀 더 검색해봐야겠다.

 

한편, URL의 context name을 없애고자 한다면, 프로젝트 우클릭 > Web Project Settings > context root를 '/'로 변경한다.

 

추가적으로 Eclipse에서 실행할 때 일일히 URL을 입력하기 귀찮으니, webapp 아래에 확장자 없는 index라는 파일을 만들어두고 이것을 실행하면 index가 들어가는 URL이 실행된다. 물론 이 때 해당 파일의 내용이 실행된다면 URL mapping에 오류가 있는 것임을 알 수 있다.


절대 경로와 상대 경로

🛠 절대 경로

루트에서 시작하여 경유하는 경로를 모두 기입하는 방식이며,

어떠한 웹 페이지나 파일이 가지는 고유한 경로이다.

 

🛠 상대 경로

현재 디렉터리를 기준으로 하여 목표로 하는 파일이 있는 곳의 위치를 나타낸다.

▪ /: 루트

▪ ./: 현재 위치

 ../: 상위 디렉터리

 

 

url-pattern에서의 /와 /*

/ 패턴을 가지는 서블릿을 디폴트 서블릿이라고 한다. 어떤 url에 해당하는 url-pattern을 가진 서블릿을 찾지 못하면 디폴트 서블릿이 요청을 받아들인다.

 

/*은 일반적인 패턴의 규칙과 동일하다. /* 패턴을 가지는 서블릿이 있다면, 모든 요청은 해당 서블릿이 받아들인다.

 

okky.kr/article/338169

'콤퓨타 왕기초 > Spring' 카테고리의 다른 글

[Spring MVC] 정적인 리소스 서비스하기  (0) 2021.04.26
[Spring MVC] ViewResolver  (0) 2021.04.26
[Spring MVC] Spring Tools 4 개발 환경 세팅  (0) 2021.04.26
[Spring MVC] Spring MVC Pattern  (0) 2021.04.26
여러 Advice  (0) 2021.04.25
Comments