-
[Spring 핵심 알기 - 1] DispatcherServlet 란? frontController 패턴 (with. 전자정부프레임워크 )Spring/Spring Core 2024. 2. 22. 14:57728x90반응형
DispatcherServlet 등장 전의 웹 개발
DispatcherServlet이 등장하기 전에는 Java 기반의 웹 애플리케이션 개발에서 주로 서블릿(Servlet)과 JSP(JavaServer Pages)를 사용했습니다. 서블릿과 JSP를 이용한 웹 개발에서는 각 요청마다 서블릿을 작성하고, 비즈니스 로직과 프레젠테이션 로직이 혼재되어 관리가 어려웠습니다.
Tomcat Server란 무엇인가?
tomcat server는 대표적인 web application server이다. spring boot에서도 기본 서버로 채택하여 셋팅하는 서버이며,
대부분에 si사업이든 플랫폼 사업이든 tomcat server를 많이 사용한다.
tomcat server는 사용자가 아래와 같이 url를 요청하면 url에 맵핑된 servlet을 돌려준다.
스프링이 나오기전에 아래와 같이 servlet 위주 개발을 많이했다.
/** * Servlet implementation class ServletParameterEx */ @WebServlet("/DoServlet") public class ServletParameterEx extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public ServletParameterEx() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); request.setCharacterEncoding("EUC-KR"); String id = request.getParameter("id_info"); String pw = request.getParameter("pw_info"); String name = request.getParameter("name_info"); String[] hobby = request.getParameterValues("hobby"); String sex = request.getParameter("sex"); System.out.println("id : " + id); System.out.println("pw : " + pw); System.out.println("name : " + name); System.out.println("sex(남/여) : " + sex); System.out.println("hobby : " + Arrays.toString(hobby)); } }
위 코드에서 나오는 '/DoServlet' 톰캣서버에서 인식하는 url이며,
톰캣 서버는 '/DoServlet' url과 맵핑되는 servlet을 찾아다가 클라이언트에게 던져주는 작업을한다.
그리고 이 과정을 적는것이 web.xml 이다.
<servlet> <servlet-name>servlet</servlet-name> <servlet-class>test.ServletController</servlet-class> </servlet> <servlet-mapping> <servlet-name>servlet</servlet-name> <url-pattern>/action.do</url-pattern> </servlet-mapping>
위처럼 web.xml 파일을 열어보면 위 와같은 내용들을 볼수있는데,
tomcat 서버는 web.xml을 읽고 클라이언트가 action.do url을 요청하면 'action.do' 와 맵핑 되어있는 ServletController클래스를 돌려준다.
*또한 web.xml에는 filter 등에 내용들도 적어줘서 url 접근전에 여러가지 로직을 수행하는 filter를 만든다.
예전엔 servlet을 만들면 이 web.xml에 각 url과 맵핑할 서블렛들을 하나하나 다 적어줘야했다.
그러다보니 web.xml은 방대해지고 관리하기 어려워 지기시작했다.
이것을 해결하기 위해 FrontController 패턴으로 만들어진 dispatcherServlet이 등장하면서 손쉽게 관리할수있게 되었다.
FrontController 패턴이란 ?
Front Controller 패턴은 웹 애플리케이션에서 모든 요청을 단일 핸들러(Front Controller)로 보내는 디자인 패턴입니다. 이 패턴은 다음과 같은 장점을 제공합니다:
- 중앙 집중화된 요청 처리: 모든 요청을 한 곳에서 처리하여 공통된 로직(인증, 로깅, 국제화 등)을 적용할 수 있습니다.
- 유지 보수 용이: 로직이 중앙 집중화되어 있어 코드의 유지 보수가 용이합니다.
- 확장성: 다양한 요청 처리 전략을 쉽게 추가하고 관리할 수 있습니다.
Spring MVC에서 DispatcherServlet는 이러한 Front Controller 역할을 합니다.
위와같은 ForntController가 Spring에서는 바로 DispatcherServlet이고, 스프링이 제공하는 스프링 서블릿/MVC의 핵심이다.
DispatcherServlet
DispatcherServlet는 Spring MVC의 프론트 컨트롤러로서, 다음과 같은 역할을 합니다:
- 요청 라우팅: 요청을 적절한 컨트롤러로 전달합니다.
- 핸들러 매핑: 요청 URL과 일치하는 컨트롤러를 찾습니다.
- 뷰 리졸버: 컨트롤러의 처리 결과를 기반으로 뷰를 선택하고 렌더링합니다.
DispatcherServlet 동작 흐름
- 클라이언트의 요청이 웹 애플리케이션에 도착합니다.
- DispatcherServlet이 요청을 수신합니다.
- HandlerMapping을 사용하여 요청 URL과 일치하는 컨트롤러를 찾습니다.
- HandlerAdapter를 사용하여 컨트롤러의 메서드를 호출합니다.
- 컨트롤러는 요청을 처리하고 ModelAndView 객체를 반환합니다.
- ViewResolver를 사용하여 뷰 이름에 해당하는 실제 뷰를 찾습니다.
- DispatcherServlet이 뷰를 렌더링하고 클라이언트에게 응답을 보냅니다.
XML을 이용한 DispatcherServlet 구성
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springmvc/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
톰캣을 위와같이 web.xml에 설정해 놓으면, 모든 url에 대한 요청에대한 맵핑 처리과정을 dispactherServlet에 위임시킨다
2.전자정부프레임워크 web.xml분석
전자정부프레임워크나 기본 스프링부트나 전부다 뼈대는 스프링인건 매한가지다. 그러므로 xml로 dispatcherServlet을 설정하거나 java 파일로 설정하는것이 다를뿐이다.
전자전부프레임워크에 web.xml을 간략이 보자면 dispatcherServlet클래스를 불러오고 init-param을 통해 dispatcher-servlet.xml 을 주입해준다.
... <listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springmvc/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.do</welcome-file> </welcome-file-list> ...
dispatcherServlet 클래스에서 상속받는 FrameworkServlet 를 보면 setContextConfigLocation 메소드가 있고 web.xml에 init-param에 넣어주는 dispatch-servlet.xml 를 넣어준다. 이제 dispatch-servlet.xml를 보자
<context:component-scan base-package="kr.co.jirandata" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> <util:properties id="config" location="classpath:/conf/config.xml" /> <mvc:annotation-driven/> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <mvc:resources mapping="/resources/**" location="/resources/" /> <mvc:resources mapping="/admin_img/**" location="/admin_img/" /> <mvc:resources mapping="/rrdtool/**" location="/rrdtool/" /> <mvc:resources mapping="/messages/**" location="classpath:/messages/" /> <!--robots --> <mvc:resources mapping="/robots.txt" location="/robots.txt" order="0"/> ... <!-- JsonView --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" id="viewResolver" p:order="0"/> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" id="jsonView"> <!-- property name="contentType" value="application/json;charset=UTF-8"/--> <property name="contentType" value="text/plain;charset=UTF-8"/> </bean>
component-scan을 통해 맵핑되어있는 컨트롤러를 찾아서 클래스를 실행시키고 ViewResolver를통해 해당 내용을 view에 던져준다. '<mvc:resource ...>' 부분은 해당 경로는 정적 리소스라고 알려준다.
728x90반응형'Spring > Spring Core' 카테고리의 다른 글