DispatcherServlet이란?, Spring MVC의 핵심

DispatcherServlet은 스프링 MVC 프로젝트의 핵심이라고 할 수 있습니다.

디스패처 서블릿은 프론트 컨트롤러로써 클라이언트로부터 어떠한 요청이 오게 되면

모든 요청을 먼저 받게 됩니다, 그리고 요청들을 세부 컨트롤러로 위임합니다.

 

이 글에서는 DispatcherServlet을 생성하는법, 작동과정, 장점에대해 기술했습니다.

 

* 프론트 컨트롤러 (Front Controller) : 서블릿 컨텐이너 제일 앞단에서 서버로 오는 모든 요청을 받아 처리하는 컨트롤러를 의미합니다.

 

DispatcherServlet 생성하기

DispatcherServlet은 사실 Spring MVC 웹프로젝트를 만들었다면 이미 생성되어 있습니다.

(Maven기준) Java Resources > Libraries > Maven Dependencies > spring-webmvc-version.jar > org.springframework.web.servlet > DispatcherServlet.class

 

저희가 해야 할 일은 DispatcherServlet 설정에 대한 XML파일을 만드는 것입니다.

 

1. web.xml 에서 설정 파일에 대한 이름과 경로를 지정합니다.

아래 코드를 web.xml에 추가해주시면 됩니다.

/WEB-INF/spring/appServlet/servlet-context.xml을 DispatcherServlet의 설정파일로 한 것입니다.

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</servlet>

 

2. 해당 설정파일 생성하기.

/WEB-INF/spring/appServlet/servlet-context.xml을 생성하고 아래 코드를 입력합니다.

주석을 통해 코드 한줄한줄에 대한 설명을 적어놓았으니 참고하시기 바랍니다.

아래 코드는 컨트롤러와 뷰를 사용하기 위한 기본적인 코드입니다.

프론트 컨트롤러이기 때문에 공통으로 처리하는 작업같은 것을 추가로 설정하여 사용합니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
    <!-- Annotation 활성화 -->
    <annotation-driven />

    <!-- 
        DispatcherServlet의 매핑 url-pattern 이 '/*' 일때
        jsp안에서 사용하는 js,css,image 등 resource 파일 불러오는데 문제가 생김
        resource file만 매핑하는 구문입니다.
        즉, resource file들은 /resources/ 위치에 만들어 사용해야함
    -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- 
        View의 prefix와 suffix지정.. @Controller에서 뷰리턴시 적용됨
        예를들어 Index Controller에서 "index"를 리턴하면 /WEB-INF/views/index.jsp 파일이 리턴됨 
    -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>
	
    <!-- 
        자바공통파일 패키지지정. 해당패키지 안에서만 Annotation명시 파일들이 사용가능
        default: @component, @Controller, @Service, @Repository
    -->
    <context:component-scan base-package="com.springweb.myapp" />
	
</beans:beans>

 

진행과정

1. 요청 접수

- FrontController 로써 http Request를 받습니다. (web.xml에 설정된 url-pattern에 해당하는 경우)

 

2. 컨트롤러로 요청 위임

- DispatcherServlet으로 들어온 요청을 요청정보(url, method 등..)를 참고해 컨트롤러에게 작업 위임합니다.

(세부 컨트롤러 찾는 것은 HandlerMapping, HandlerAddapter라는 전략에서 진행함)

 

3. 컨트롤러에서 작업 진행

- 요청이 위임된 컨트롤러에서 작업을 진행합니다.

- 컨트롤러에서 작업이 끝나면 다시 DispatcherServlet으로 결과를 리턴합니다. (뷰, 모델)

 

4. 뷰 호출 (모델 참조)

- DispatcherServlet은 뷰 오브젝트에 모델 넘겨주며 최종 결과물을 생성합니다.

 

5. 최종 응답

- DispatcherServlet은 공통으로 진행해야 할 후처리 작업이 있는지 확인 후 수행합니다.

- 수행 후 HttpServletResponse에 있는 최종 결과를 서블릿 컨테이너에게 돌려주고

컨테이너는 클라이언트(브라우저)에 전송하여 응답합니다.

 

장점

1. @Controller 어노테이션

Spring 이 없던 시절에는 주소마다 Servlet 객체를 생성하고 web.xml에 일일이 매핑해줘야 했다.

웹에는 우리가 접속하는 페이지가 한두개가 아닌데, 프로젝트에는 서블릿으로 넘쳐나게 된다

(서블릿 은 하나당 하나의 경로만 담당..)

@Controller 어노테이션으로 컨트롤러를 만들고 @RequestMapping 어노테이션으로 주소를 연결하면 DispatcherServlet에서 해당 컨트롤러 > 함수로 연결해줌으로 서블릿을 일일이 만들 필요가 없어졌다.

@Controller
public class MainController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String Index() {
    	return "index";
    }
    
    @RequestMapping(value = "/main.do", method = RequestMethod.GET)
    public String Main() {
    	return "main";
    }
}

 

2. 모든 주소의 공통적인 전처리, 후처리 작업을 할 수 있다.

주소마다 Servlet을 만들어 사용할 때는 굉장히 까다로웠던 작업인데

DispatcherServlet을 활용하여 굉장히 간단히 처리할 수 있게 되었다.