### Dispatcher Servlet에 대한 자세한 설명
**Dispatcher Servlet**은 Spring MVC 프레임워크의 핵심 구성 요소 중 하나로, 웹 애플리케이션의 요청을 처리하고 적절한 컨트롤러에 요청을 전달하는 역할을 합니다. Dispatcher Servlet은 프론트 컨트롤러(front controller) 디자인 패턴을 구현한 것으로, 모든 요청을 중앙에서 처리하고 응답을 생성하는 과정을 통제합니다.
### Dispatcher Servlet의 역할과 기능
1. **요청 수신 및 분배**: Dispatcher Servlet은 클라이언트로부터 들어오는 모든 HTTP 요청을 수신합니다. URL 패턴에 따라 요청을 적절한 컨트롤러에 분배합니다.
2. **Handler Mapping**: 요청 URL을 기반으로 적절한 핸들러(컨트롤러)를 찾습니다. 이를 위해 다양한 핸들러 매핑 전략을 사용합니다.
3. **Handler Adapter**: 핸들러를 실행할 수 있는 적절한 어댑터를 찾습니다. 어댑터는 핸들러를 호출하고, 핸들러의 결과를 ModelAndView 객체로 반환합니다.
4. **ModelAndView 처리**: 핸들러가 반환한 ModelAndView 객체를 처리하여, 뷰(view)를 생성하고 모델(model) 데이터를 전달합니다.
5. **View Resolver**: 논리적인 뷰 이름을 실제 뷰 객체로 변환하는 뷰 리졸버를 사용합니다.
6. **뷰 렌더링**: 최종적으로 뷰를 렌더링하여 클라이언트에게 응답을 반환합니다.
### Dispatcher Servlet의 작동 흐름
Dispatcher Servlet의 작동 흐름은 다음과 같습니다:
1. **요청 수신**: 클라이언트로부터 HTTP 요청이 들어오면, Dispatcher Servlet이 이를 수신합니다.
2. **핸들러 매핑**: 요청 URL을 기반으로 핸들러 매핑을 수행하여 적절한 컨트롤러를 찾습니다. 이는 HandlerMapping 인터페이스를 구현한 다양한 매핑 전략을 통해 이루어집니다.
3. **핸들러 어댑터**: 선택된 컨트롤러를 실행하기 위해 핸들러 어댑터를 찾습니다. 이는 HandlerAdapter 인터페이스를 구현한 객체를 통해 이루어집니다.
4. **핸들러 실행**: 핸들러 어댑터가 컨트롤러를 호출하여 요청을 처리하고, ModelAndView 객체를 반환합니다.
5. **뷰 리졸버**: 반환된 ModelAndView 객체의 논리적 뷰 이름을 실제 뷰 객체로 변환합니다. 이는 ViewResolver 인터페이스를 구현한 객체를 통해 이루어집니다.
6. **모델 데이터 병합 및 뷰 렌더링**: 모델 데이터를 뷰에 병합하여 최종 뷰를 렌더링합니다.
7. **응답 반환**: 렌더링된 뷰를 클라이언트에게 응답으로 반환합니다.
### Dispatcher Servlet 설정
Spring MVC에서는 Dispatcher Servlet을 설정하기 위해 `web.xml` 파일에 다음과 같이 정의합니다:
```xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- Dispatcher Servlet 정의 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Dispatcher Servlet 매핑 -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
```
위의 설정에서 Dispatcher Servlet은 `dispatcher`라는 이름으로 정의되며, `/` URL 패턴에 매핑되어 모든 요청을 처리하도록 설정됩니다. `contextConfigLocation` 초기화 파라미터는 Spring 설정 파일의 위치를 지정합니다.
### Spring 설정 파일 (dispatcher-config.xml)
Dispatcher Servlet의 설정을 포함한 Spring 설정 파일은 다음과 같습니다:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 컨트롤러 패키지 스캔 -->
<context:component-scan base-package="com.example.controllers"/>
<!-- MVC 설정 -->
<mvc:annotation-driven/>
<!-- View Resolver 설정 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
```
위의 설정 파일에서 주요 요소는 다음과 같습니다:
1. **패키지 스캔**: `context:component-scan`을 사용하여 컨트롤러가 위치한 패키지를 스캔합니다.
2. **MVC 설정**: `mvc:annotation-driven`을 통해 애노테이션 기반의 Spring MVC를 활성화합니다.
3. **뷰 리졸버**: `InternalResourceViewResolver`를 설정하여 논리적인 뷰 이름을 JSP 파일로 매핑합니다.
### Dispatcher Servlet의 주요 인터페이스와 클래스
1. **HandlerMapping**: 요청 URL을 적절한 핸들러(컨트롤러)에 매핑하는 역할을 합니다. 주요 구현체로는 `RequestMappingHandlerMapping`, `BeanNameUrlHandlerMapping` 등이 있습니다.
2. **HandlerAdapter**: 선택된 핸들러를 실행하는 역할을 합니다. 주요 구현체로는 `RequestMappingHandlerAdapter`, `SimpleControllerHandlerAdapter` 등이 있습니다.
3. **ViewResolver**: 논리적인 뷰 이름을 실제 뷰 객체로 변환하는 역할을 합니다. 주요 구현체로는 `InternalResourceViewResolver`, `BeanNameViewResolver` 등이 있습니다.
4. **LocaleResolver**: 요청의 로케일 정보를 결정하는 역할을 합니다.
5. **ThemeResolver**: 요청의 테마 정보를 결정하는 역할을 합니다.
### Dispatcher Servlet의 확장성과 커스터마이징
Dispatcher Servlet은 다양한 방식으로 확장하고 커스터마이징할 수 있습니다:
1. **커스텀 핸들러 매핑**: `HandlerMapping` 인터페이스를 구현하여 사용자 정의 핸들러 매핑 전략을 추가할 수 있습니다.
2. **커스텀 핸들러 어댑터**: `HandlerAdapter` 인터페이스를 구현하여 사용자 정의 핸들러 어댑터를 추가할 수 있습니다.
3. **커스텀 뷰 리졸버**: `ViewResolver` 인터페이스를 구현하여 사용자 정의 뷰 리졸버를 추가할 수 있습니다.
4. **인터셉터**: `HandlerInterceptor` 인터페이스를 구현하여 요청 전후에 특정 작업을 수행할 수 있습니다. 이는 `preHandle`, `postHandle`, `afterCompletion` 메서드를 통해 구현합니다.
```java
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 요청 처리 전
return true; // false 반환 시 요청 처리를 중단합니다.
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 요청 처리 후, 뷰 렌더링 전
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 뷰 렌더링 후
}
}
```
위와 같이 인터셉터를 구현하고, Spring 설정 파일에 추가하여 사용할 수 있습니다:
```xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.example.interceptors.CustomInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
```
### 결론
Dispatcher Servlet은 Spring MVC의 중심으로, 모든 HTTP 요청을 중앙에서 처리하고 적절한 컨트롤러에 분배하는 역할을 합니다. 이를 통해 애플리케이션의 흐름을 효과적으로 관리하고, 요청 처리, 뷰 렌더링 등의 과
정을 효율적으로 통제할 수 있습니다. Dispatcher Servlet을 이해하고 적절하게 활용하면 Spring MVC 애플리케이션을 더욱 효과적으로 개발하고 유지 관리할 수 있습니다.
'게으른 개발자의 끄적거림' 카테고리의 다른 글
HTTP란? (구조, 동작 방식, 요청 메서드 등) (0) | 2024.06.20 |
---|---|
소켓(SOCKET)통신 이란? (0) | 2024.06.19 |
web.xml이란? web.xml 구성 요소 (0) | 2024.06.18 |
Java 서블릿이란? (feat. 서블릿 컨테이너) (0) | 2024.06.17 |
HTTP 405error란? (해결 방법) (0) | 2024.06.13 |