1. 개요
DispatcherServlet은 Spring 웹 애플리케이션에서 전면 컨트롤러입니다. Spring MVC에서 웹 애플리케이션 및 REST 서비스를 생성하는 데 사용됩니다. 전통적인 Spring 웹 애플리케이션에서 이 서블릿은 web.xml 파일에 정의되어 있습니다.
이 사용방법(예제)에서는 web.xml 파일의 코드를 Spring Boot 애플리케이션의 DispatcherServlet 으로 마이그레이션 합니다. 또한 web.xml의 Filter , Servlet 및 Listener 클래스를 Spring Boot 애플리케이션에 매핑 합니다.
2. 메이븐 의존성
먼저 pom.xml 파일에 spring-boot-starter-web Maven 의존성을 추가해야 합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3. 디스패처 서블릿
DispatcherServlet 은 모든 HTTP 요청을 수신하고 이를 컨트롤러 클래스에 위임합니다.
Servlet 3.x 사양 이전에는 DispatcherServlet 이 Spring MVC 애플리케이션 의 web.xml 파일에 등록되었습니다 . Servlet 3.x 사양부터 ServletContainerInitializer를 사용하여 프로그래밍 방식으로 서블릿을 등록할 수 있습니다 .
web.xml 파일 에서 DispatcherServlet 예제 구성을 살펴보겠습니다 .
<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>
Spring Boot는 Spring MVC를 사용하여 웹 애플리케이션을 개발하기 위한 spring-boot-starter-web 라이브러리를 제공합니다 . Spring Boot의 주요 기능 중 하나는 자동 구성입니다. Spring Boot 자동 구성은 DispatcherServlet을 자동으로 등록하고 구성합니다 . 따라서 DispatcherServlet을 수동으로 등록할 필요가 없습니다 .
기본적으로 spring-boot-starter-web 스타터는 DispatcherServlet 을 URL 패턴 "/"로 구성합니다. 따라서 web.xml 파일 에서 위의 DispatcherServlet 예제에 대한 추가 구성을 완료할 필요가 없습니다 . 그러나 server.servlet을 사용하여 URL 패턴을 사용자 정의할 수 있습니다 . * application.properties 파일에서:
server.servlet.context-path=/demo
spring.mvc.servlet.path=/baeldung
이러한 사용자 정의를 통해 DispatcherServlet 은 URL 패턴 /baeldung 을 처리하도록 구성되고 루트 contextPath 는 /demo가 됩니다. 따라서 DispatcherServlet 은 http://localhost:8080/demo/baeldung/ 에서 수신 대기합니다 .
4. 애플리케이션 구성
Spring MVC 웹 애플리케이션은 web.xml 파일을 배포 디스크립터 파일로 사용합니다. 또한 web.xml 파일 에서 URL 경로와 서블릿 간의 매핑을 정의합니다 .
이것은 더 이상 Spring Boot의 경우가 아닙니다. 특별한 필터가 필요한 경우 Java 클래스 구성에 등록할 수 있습니다. 의 web.xml의 파일 필터, 서블릿, 청취자가 포함되어 있습니다.
전통적인 Spring MVC에서 현대적인 Spring Boot 애플리케이션으로 마이그레이션하고 싶을 때 web.xml 을 새로운 Spring Boot 애플리케이션으로 어떻게 이식할 수 있습니까? Spring Boot 애플리케이션에서 이러한 개념을 여러 가지 방법으로 추가할 수 있습니다.
4.1. 필터 등록
Filter 인터페이스 를 구현하여 필터를 생성해 보겠습니다 .
@Component
public class CustomFilter implements Filter {
Logger logger = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("CustomFilter is invoked");
chain.doFilter(request, response);
}
// other methods
}
Without Spring Boot, we would configure our CustomFilter in the web.xml file:
<filter>
<filter-name>customFilter</filter-name>
<filter-class>CustomFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>customFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In order for Spring Boot to be able to recognize a filter, we just needed to define it as a bean with the @Component annotation.
4.2. Registering a Servlet
Let's define a servlet by extending the HttpServlet class:
public class CustomServlet extends HttpServlet {
Logger logger = LoggerFactory.getLogger(CustomServlet.class);
@Override
protected void doGet(
HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
logger.info("CustomServlet doGet() method is invoked");
super.doGet(req, resp);
}
@Override
protected void doPost(
HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
logger.info("CustomServlet doPost() method is invoked");
super.doPost(req, resp);
}
}
Without Spring Boot, we would configure our CustomServlet in the web.xml file:
<servlet>
<servlet-name>customServlet</servlet-name>
<servlet-class>CustomServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>customServlet</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
In a Spring Boot application, the servlet is registered either as a Spring @Bean or by scanning the @WebServlet annotated classes with an embedded container.
With the Spring @Bean approach, we can use the ServletRegistrationBean class to register the servlet.
So, we'll define CustomServlet as a bean with the ServletRegistrationBean class:
@Bean
public ServletRegistrationBean customServletBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(new CustomServlet(), "/servlet");
return bean;
}
4.3. Registering a Listener
Let's define a listener by extending the ServletContextListener class:
public class CustomListener implements ServletContextListener {
Logger logger = LoggerFactory.getLogger(CustomListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("CustomListener is initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("CustomListener is destroyed");
}
}
Without Spring Boot, we would configure our CustomListener in the web.xml file:
<listener>
<listener-class>CustomListener</listener-class>
</listener>
To define a listener in a Spring Boot application, we can use either the @Bean or @WebListener annotations.
Spring @Bean 접근 방식으로 ServletListenerRegistrationBean 클래스를 사용 하여 Listener 를 등록 할 수 있습니다 .
따라서 CustomListener 를 ServletListenerRegistrationBean 클래스를 사용하여 빈으로 정의해 보겠습니다 .
@Bean
public ServletListenerRegistrationBean<ServletContextListener> customListenerBean() {
ServletListenerRegistrationBean<ServletContextListener> bean = new ServletListenerRegistrationBean();
bean.setListener(new CustomListener());
return bean;
}
애플리케이션을 시작할 때 리스너가 성공적으로 초기화되었는지 확인하기 위해 로그 출력을 확인할 수 있습니다.
2020-09-28 08:50:30.872 INFO 19612 --- [main] c.baeldung.demo.listener.CustomListener: CustomListener is initialized
5. 결론
이 빠른 예제에서 우리는 Spring Boot 애플리케이션에서 필터 , 서블릿 , 리스너 를 포함하여 DispatcherServlet 및 web.xml 요소 를 정의하는 방법을 보았습니다 . 그리고 항상 그렇듯이 위의 예제에 대한 소스 코드는 GitHub 에서 찾을 수 있습니다 .