스프링 MVC 동작 원리(4) : 서블릿 리스너와 필터

de_sj_awa·2021년 6월 26일
0

4. 서블릿 리스너와 필터

서블릿 리스너

  • 웹 애플리케이션에서 발생하는 주요 이벤트를 감지하고 각 이벤트에 특별한 작업이 필요한 경우에 사용할 수 있다.
    - 서블릿 컨텍스트 수준의 이벤트
    1. 컨텍스트 라이프사이클 이벤트
    2. 컨텍스트 애트리뷰트 변경 이벤트
    - 세션 수준의 이벤트
    1. 세션 라이프사이클 이벤트
    2. 세션 애트리뷰트 변경 이벤트
  1. 서블릿 컨텍스트 리스너 생성 : 컨텍스트 라이프사이클 이벤트 감지
public class MyListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Context Initialized");
        sce.getServletContext().setAttribute("name", "spring");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Context Destroyed");
    }
}
  1. web.xml에 리스너 등록
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <listener>
    <listener-class>org.example.servlet02.MyListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.example.servlet02.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>
  1. 서블릿 클래스에서 리스너 활용
public class HelloServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("init");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().println("<html>");
        resp.getWriter().println("<head>");
        resp.getWriter().println("<body>");
        resp.getWriter().println("<h1>Hello, " + getservletContext().getAttribute("name") + "</h1>");
        resp.getWriter().println("Hello Servlet");
        resp.getWriter().println("</body>");
        resp.getWriter().println("</head>");
        resp.getWriter().println("</html>");
    }

    private Object getName() {
        return getServletContext().getAttribute("name");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

서블릿 필터

  • 들어온 요청을 서블릿으로 보내고, 또 서블릿이 작성한 응답을 클라이언트로 보내기 전에 특별한 처리가 필요한 경우에 사용할 수 있다.
  • 체인 형태의 구조

  1. Filter 인터페이스를 implement한 필터 클래스 생성
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter Init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("filter");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("Filter Destroy");
    }
}
  1. web.xml에서 필터 등록
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>org.example.servlet02.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <servlet-name>hello</servlet-name>
  </filter-mapping>
  <listener>
    <listener-class>org.example.servlet02.MyListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.example.servlet02.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

실행 순서

서블릿 리스너가 서블릿 초기화 이벤트 감지(contextInitialized) -> 필터가 초기화(init) -> 서블릿 초기화(init) -> 필터 실행(doFilter) -> 서블릿 실행(doGet) -> 서블릿 종료(destroy) -> 필터 종료(destroy) -> 서블릿 리스너가 서블릿 종료 이벤트 감지(contextDestroyed)

참고

profile
이것저것 관심많은 개발자.

0개의 댓글