서블릿 리스너
: 서블릿 컨테이너에서 발생하는 이벤트 (lifecycle의 변화, session의 변화, attribute의 변화...)에 특정한 코드를 실행해야 할 때 사용
언제 사용되는가?
- 서블릿 컨테이너 구동 시 데이터베이스 커넥션을 맺어놓고 해당 커넥션을 서블릿 애플리케이션에서 만든 여러 가지 서블릿에 제공하는 경우 (참고로 서블릿은 여러 개 생성이 가능하다.)
- 서블릿 콘텍스트 내부의 서블릿 애트리뷰트에 접근하여 DB 커넥션을 꺼내 사용하는 경우
- 서블릿 컨테이너 종료 시 리스너를 활용하여 초기에 만들어 두었던 DB 커넥션을 정리하는 경우
-
서블릿 콘텍스트 수준의 이벤트
-
콘텍스트 라이프사이클 이벤트
-
콘텍스트 애트리뷰트 변경 이벤트
-
세션 수준의 이벤트
-
세션 라이프사이클 이벤트
-
세션 애트리뷰트 변경 이벤트
서블릿 필터
: 요청이 들어왔을 때 doGet 혹은 doPost로 가지만 이 과정에서 특정한 사전작업을 하고 싶은 경우에 사용
언제 사용되는가?
- 들어온 요청을 서블릿으로 보내고, 또 서블릿이 작성한 응답을 클라이언트로 보내기 전에 특별한 처리가 필요한 경우에 사용할 수 있다.
- 체인 형태의 구조
- 동시 다발적으로 Servlet Container와 Servlet이 communication 하는 것이 아니라 chain 형태로 순차적으로 진행된다.
- web.xml에 정의한 순서대로 진행된다.
- 반드시 다음 chain으로 넘어가게 코드를 작성해야 된다.
서블릿 리스너 생성
Listener 생성
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Context Initialized");
sce.getServletContext().setAttribute("name","choi");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Context Destroyed");
}
}
web.xml Listener 경로 등록
<listener>
<listener-class>me.choi.MyListener</listener-class>
</listener>
servlet에 등록하였던 Listener 호출
@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," + getName() + "</h1>");
resp.getWriter().println("</body>");
resp.getWriter().println("</head>");
resp.getWriter().println("</html>");
}
private Object getName() {
return getServletContext().getAttribute("name");
}
실행 시
Connected to server
[2020-01-11 04:15:11,732] Artifact java-servlet-demo:war exploded: Artifact is being deployed, please wait...
Context Initialized
[2020-01-11 04:15:13,143] Artifact java-servlet-demo:war exploded: Artifact is deployed successfully
[2020-01-11 04:15:13,143] Artifact java-servlet-demo:war exploded: Deploy took 1,411 milliseconds
11-Jan-2020 16:15:21.344 정보 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory 웹 애플리케이션 디렉토리 [/Users/junwoochoi/Downloads/apache-tomcat-9.0.30/webapps/manager]을(를) 배치합니다.
11-Jan-2020 16:15:21.399 정보 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory 웹 애플리케이션 디렉토리 [/Users/junwoochoi/Downloads/apache-tomcat-9.0.30/webapps/manager]에 대한 배치가 [54] 밀리초에 완료되었습니다.
init
doGet
doGet
로그 메시지를 살펴보자면
서버가 연결되고 ServletContext가 실행되는 시점(초기화하는 시점)에 Listener가 실행됨을 볼 수 있다.
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Context Initialized");
sce.getServletContext().setAttribute("name","choi");
}
종료 시
destroy
Context Destroyed
11-Jan-2020 16:19:26.335 정보 [main] org.apache.coyote.AbstractProtocol.stop 프로토콜 핸들러 ["http-nio-8080"]을(를) 중지시킵니다.
11-Jan-2020 16:19:26.338 정보 [main] org.apache.coyote.AbstractProtocol.stop 프로토콜 핸들러 ["ajp-nio-8009"]을(를) 중지시킵니다.
11-Jan-2020 16:19:26.342 정보 [main] org.apache.coyote.AbstractProtocol.destroy 프로토콜 핸들러 ["http-nio-8080"]을(를) 소멸시킵니다.
11-Jan-2020 16:19:26.343 정보 [main] org.apache.coyote.AbstractProtocol.destroy 프로토콜 핸들러 ["ajp-nio-8009"]을(를) 소멸시킵니다.
Disconnected from server
서블릿이 종료가 되고 ServletContext가 종료되며 마지막으로 서버가 끊기게 된다.
서블릿 필터 생성
Listener는 servletcontext에서 servlet로 가능 과정이다. (Listenr 이후의 작업)
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter Init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("Filter Destroy");
}
}
web.xml 설정
<filter>
<filter-name>myfilter</filter-name>
<filter-class>me.choi.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<servlet-name>hello</servlet-name>
</filter-mapping>
실행결과 servletcontext를 초기화하고 servlet으로 가는 과정에서 Filter를 거친다는 것을 볼 수 있다.
코드 참조
https://github.com/mike6321/Spring/tree/master/SpringMVC/java-servlet-demo
'Spring > Spring MVC' 카테고리의 다른 글
(SERVLET) 스프링 MVC 연동 (0) | 2020.01.12 |
---|---|
(SERVLET) 스프링 IoC 컨테이너 연동 (0) | 2020.01.11 |
(SERVLET) 서블릿 애플리케이션 개발 (0) | 2020.01.11 |
(SERVLET) Servlet 개요 (0) | 2020.01.11 |
(SERVLET) SPRING MVC 개요 - 간단한 MVC 만들기 (0) | 2020.01.11 |