ServletRegistrationBean 이란?

이름에도 나와있다시피, Servlet(서블릿) Registration(등록) Bean(빈 객체)이다.

먼저 간단하게 설명하자면, Spring 에서 서블릿을 등록하고 특정 URL 로 매핑하기 위한 도구이다.

 

그런데 이제, 서블릿을 `커스텀(Custom)` 하게 개발자 입맛대로 추가할 수 있도록 도와주는 도구이다.

 

Spring 에서 Servlet 을 원래 어떻게 다루고 있나? (기본 설정에 대하여)

1. @SpringBootApplication 어노테이션이 달린 메인 실행 클래스에서, SpringApplication.run() 을 기동한다.

2. 이 과정에서 ServletContext 가 만들어진다.

3. 또한 DispatcherServlet 을 등록하여, 모든 요청을 처리하도록 URL 을 "/" 로 매핑해준다.

@Bean
public DispatcherServlet dispatcherServlet() {
    return new DispatcherServlet();
}

@Bean
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
    return new ServletRegistrationBean<>(dispatcherServlet, "/");
}

 

DispatcherServlet 을 자동 등록하는 코드를 보면 있지 않은가?

바로 ~ `ServletRegistrationBean` 이라는 객체에 dispatcherServlet 이 묶여있는 것을.

 

 

 

 

그 전에 조금의 개념 정리부터.

 

ServletContext 는 서블릿의 환경 관리자이다.

애플리케이션의 전역 정보나, 서블릿 간 데이터를 공유하는 일 등을 도맡고 있다.

 

DispatcherServlet 은 서블릿의 길을 찾아주는 지도이다.

SpringMVC 를 구성하는 가장 핵심 요소인 중앙 컨트롤러이다. 스프링에 존재하는 모든 컨트롤러들이 길을 잘 찾아서 요청을 보내고 응답을 받을 수 있도록 도와주는 역할을 한다.

 

 

자자,, 이제 다시 돌아와서

ServletRegistrationBean 으로 `커스텀` 서블릿 처리를 등록하는 방법.

@Configuration
public class MyServletConfig {

    @Bean
    public ServletRegistrationBean<HttpServlet> myServlet() {
        HttpServlet myCustomServlet = new HttpServlet() {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
                resp.getWriter().write("Hello from My Custom Servlet!");
            }
        };

        ServletRegistrationBean<HttpServlet> registrationBean = new ServletRegistrationBean<>(myCustomServlet, "/custom/*");
        registrationBean.setName("myCustomServlet");
        registrationBean.setLoadOnStartup(1); // 초기화 우선순위 설정
        return registrationBean;
    }
}

 

 

  • 먼저 @Configuration 애노테이션이 달린 설정 클래스를 생성한다.
  • ServletRegistrationBean<?> 객체를 반환하는 메소드를 생성하고, Bean 으로 등록한다.
  • ? 에 들어가는 객체는 Servlet 을 반드시 상속받은 객체여야 한다.
  • 또한 Servlet 을 상속받은 객체는 doGet(..) 혹은 doPost(..) 등의 요청 방식에 대해서 메소드로 정의해야 한다.
  • ServletRegistrationBean 객체를 반환하는 메소드안에서는 이제, 연결할 mapping URL 정보초기 설정 parameter 들 등을 설정한 ServletRegistrationBean 객체를 반환한다.

 

위 예시에서는 익명 클래스를 이용하여 바로 구현했지만, 만약 Servlet 클래스를 생성했다면,

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.getWriter().write("Handled GET request");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.getWriter().write("Handled POST request");
}

 

위와 같이 각 요청방식에 해당하는 구현 방식을 정의해야 할 것이다.

 

 

질문 1. url 은 하나만 지정할 수 있는가?

아니다. url 배열로 지정이 가능하다

 

질문 2. 그렇다면 같은 Servlet 객체를 반환할때 여러 url 을 지정했어도 다른 동작 방식을 주고 싶다면?

@Bean
public ServletRegistrationBean<HttpServlet> multiBehaviorServlet() {
    HttpServlet servlet = new HttpServlet() {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            String path = req.getRequestURI();
            if (path.contains("/path1")) {
                resp.getWriter().write("Handled by Path 1");
            } else if (path.contains("/path2")) {
                resp.getWriter().write("Handled by Path 2");
            } else {
                resp.getWriter().write("Handled by Default Path");
            }
        }
    };

    ServletRegistrationBean<HttpServlet> registrationBean = new ServletRegistrationBean<>(servlet, "/path1/*", "/path2/*", "/default/*");
    return registrationBean;
}

 

이런 방식으로 Servlet 객체를 조정하면 된다.

 

 

질문 3. 하나의 url 에 get 방식 post 방식 둘다 정의되는 것인가?

맞다.

+ Recent posts