Spring/Spring MVC

[Spring] Servlet listener, filter

TheWing 2020. 11. 6. 20:01

Servlet listener,filter

Servlet listiener

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

Servlet filter

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

  • Servlet Listener는 Servlet Container 영역 위에있다
  • Servlet Container에서 바로 Servlet에 가는 것이 아니라 Filter를 거치고 간다

Servlet Context 예제

  • HelloServlet 클래스를 HttpServlet 상속받아 생성
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {

    @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("</head>");
        resp.getWriter().println("<body>");
        resp.getWriter().println("<h1>Hello, " + getName() + "</h1>");
        resp.getWriter().println("</body>");

        resp.getWriter().println("</html>");
    }

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

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

    @Override
    public void init() throws ServletException {
        System.out.println("init");
    }
}
  • MyListener클래스를 ServletContextListener를 구현하여 생성
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("context Initialized");
        sce.getServletContext().setAttribute("name", "thewing");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("context Destroyed");
    }
}
  • 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>
  <listener>
    <listener-class>MyListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>
  • Run 결과

  • 톰캣 종료 결과

  • Run시 첫 번째로 Servlet Context가 초기화된다 http://localhost:8080/hello 입력시 Servlet 메소드 호출 init, doGet 출력 한뒤 톰캣을 종료하면 Servlet이 먼저 destory되고나서 Servlet Context가 Destroy된다

Servlet Filter 예제

  • MyFilter 클래스 생성
import javax.servlet.*;
import java.io.IOException;

public class MyFilter  implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("Filter");
        chain.doFilter(request,response); //Filter를 연결하도록 체이닝을 해준다.
    }

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

    @Override
    public void destroy() {
        System.out.println("Filter Destory");
    }
}
  • 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>
  <listener>
    <listener-class>MyListener</listener-class>
  </listener>
  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>MyFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <servlet-name>hello</servlet-name>
  </filter-mapping>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

 

context Initialized
Filter init
init
Filter
doGet
destroy
Filter Destory
context Destroyed
  • Servlet Context가 먼저 초기화 → Filter 초기화 → Servlet 초기화 → Get() → Servlet 소멸 → Filter 소멸 → Servlet Context 소멸

결론

  • 라이프 사이클은 Servlet Context , Filter, Servlet 순으로 초기화되고 Get() 요청 후 Servlet,Filter, Servlet Context 순으로 소멸된다

Reference