Java 프레임워크 만들기 - JSP

자바 서블릿 콘텍스트 리스너 만들기 - Java Servlet Listener ServletContext , 이클립스(Eclipse)

carrotweb 2021. 4. 9. 12:45
728x90
반응형

Listener(리스너)는 이벤트가 발생할 때 이벤트를 수신하여 처리하기 기능을 합니다.

Listener(리스너)는 "@WebListener" 어노테이션으로 설정하거나 "web.xml"에 "<listener>"를 등록하여 설정할 수 있습니다.

Listener(리스너)는 EventListener(이벤트 리스너) 인터페이스를 계승을 받고 "ServletContextListener", "ServletContextAttributeListener", "ServletRequestListener", "ServletRequestAttributeListener", "AsyncListener", "HttpSessionListener", "HttpSessionAttributeListener", "HttpSessionActivationListener", "HttpSessionBindingListener", "HttpSessionBindingListener" 중 인터페이스를 계승받아 구현하면 됩니다.

"ServletContextListener"는 "ServletContext" 라이프 사이클 변경에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about ServletContext lifecycle changes.")

"ServletContextListener"는 "contextInitialized"는 초기화될 때, "contextDestroyed"는 파기될 때 호출됩니다.

"ServletContextAttributeListener"는 "ServletContext" 속성 변경에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about ServletContext attribute changes.")

"ServletContextAttributeListener"는 "attributeAdded"는 속성이 추가될 때, "attributeRemoved"는 속성이 삭제될 때 호출됩니다.

"ServletRequestListener"는 "ServletRequest"가 웹 애플리케이션의 범위에서 들어오거나 나가는 요청에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about requests coming into and going out of scope of a web application.")

"ServletRequestListener"는 "requestInitialized"는 요청이 초기화될 때, "requestDestroyed"는 요청이 파기될 때 호출됩니다. 요청 초기화 시점은 첫 번째 서블릿 또는 필터에 들어가려고 할 때이고 요청 파기 시점은 마지막 서블릿 또는 첫 번째 필터를 종료할 때입니다.

"ServletRequestAttributeListener"는 "ServletRequest" 속성 변경에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about ServletRequest attribute changes.")

"ServletRequestAttributeListener"는 "attributeAdded"는 요청 속성이 추가될 때, "attributeRemoved"는 요청 속성이 삭제될 때, "attributeReplaced"는 요청 속성이 변경될 때 호출됩니다.

"AsyncListener"는 "ServletRequest"이 비동기 작업이 완료 되거나 시간이 초가 되는 경우에 알림 이벤트를 수신하기 위한 인터페이스입니다.

"AsyncListener"는 "onComplete", "onTimeout", "onError", "onStartAsync"를 호출합니다.

"HttpSessionListener"는 "HttpSession" 라이프 사이클 변경에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about HttpSession lifecycle changes.")

"HttpSessionListener"는 "sessionCreated"는 세션이 생성될 때, "sessionDestroyed"는 세션이 파기될 때 호출됩니다.

"HttpSessionAttributeListener"는 "HttpSession" 속성 변경에 대해 알림 이벤트를 수신하기 위한 인터페이스입니다. ("Interface for receiving notification events about HttpSession attribute changes.")

"HttpSessionAttributeListener"는 "attributeAdded"는 세션 속성이 추가될 때, "attributeRemoved"는 세션 속성이 삭제될 때, "attributeReplaced"는 세션 속성이 변경될 때 호출됩니다.

"HttpSessionActivationListener"는 "HttpSession"이 다른 VM으로 이동할 때 활성되거나 비 활성될 때 알림 이벤트를 수신하기 위한 인터페이스입니다.

"HttpSessionActivationListener"는 "sessionDidActivate"는 세션을 다른 VM으로 이동한 후 세션이 활성화될 때, "sessionWillPassivate"는 세션을 다른 VM으로 이동하기 전 세션이 비활성화되기 전에 호출됩니다.

"HttpSessionBindingListener"는 "HttpSession"에 객체가 바인딩되거나 바인딩이 해제될때 알림 이벤트를 수신하기 위한 인터페이스입니다.

"HttpSessionBindingListener"에서 "valueBound"는 세션에 객체가 바인딩될 때, "valueUnbound"는 세션에 객체가 바인딩이 해제될 때 호출됩니다.

"HttpSessionIdListener"는 "HttpSession"의 Id가 변경될 때 알림 이벤트를 수신하기 위한 인터페이스입니다.("Interface for receiving notification events about HttpSession id changes.")

"HttpSessionIdListener"는 "sessionIdChanged"는 세션에서 세션 ID가 변경될 때 호출됩니다.

"ServletContextListener", "ServletContextAttributeListener"을 만들고 이벤트가 호출되는 시점을 출력을 통해 확인해보겠습니다.

1. "test2" 프로젝트의 "Java Resources"에서 "src/main/java"의 "com.home.project.test2"를 선택한 후 오른쪽 버튼을 클릭하여 컨텍스트 메뉴 [New > Package]를 클릭하여 "Name"의 기존 패키지명에 ".listener"를 추가하고 "Finish"버튼을 클릭합니다. 추가된 "com.hom.project.test2.listener"에서 오른쪽 버튼을 클릭하여 컨텍스트 메뉴 [New > Listener]를 클릭합니다.

 

"Create Listener"창이 나타납니다.

패키지를 선택하고 컨텍스트 메뉴 [New > Listener]를 클릭하면 자동으로 "Java package"가 지정되어 나옵니다.

"Class name"에 "TestServletContextListener"를 입력하고 "Next >"버튼을 클릭합니다.

이벤트를 수신하고 싶은 이벤트를 선택합니다.

"Servlet context events"의 "Lifecycle"를 체크합니다.

"Next >"버튼을 클릭합니다. 또는 "Finish"버튼을 클릭해서 완료할 수 있습니다.

인터페이스를 추가하거나 삭제합니다.

"Interfaces"에 "Javax.servlet.ServletContextListener"인터페이스를 받아 구현하는 것을 알 수 있습니다.

"Finish"버튼을 클릭합니다.

"TestServletContextListener.java"파일이 생성됩니다.

현재 "Dynamic Web Module 3.1"로 구성되어 있어 "TestServletContextListener.java"에 "@WebListener" 어노테이션을 사용하고 있습니다.

@WebListener

"web.xml"에서 구성하고 싶다면 "TestServletContextListener.java"에 "@WebListener" 어노테이션을 삭제한 후 "web.xml"에 다음과 같이 추가하면 됩니다.

<listener>
	<listener-class>com.home.project.test2.listener.TestServletContextListener</listener-class>
</listener>

처리 방식은 동일합니다.

"TestServletContextListener.java"의 "constructor"와 "contextInitialized", "contextDestroyed"에 출력문을 코딩하여 어느 시점에서 호출되는 지를 확인해하기 위해서입니다.

public TestServletContextListener() {
	System.out.println("ServletContextListener 생성자 실행");
}

public void contextInitialized(ServletContextEvent sce)  { 
	System.out.println("ServletContext 초기화 실행");
}

public void contextDestroyed(ServletContextEvent sce)  { 
	System.out.println("ServletContext 파괴 실행");
}

 

2. "Servers"탭에서 "Tomcat8"를 선택하고 "start"버튼(start the server)을 클릭하고 "Console"탭를 클릭합니다.

[Console]

ServletContextListener 생성자 실행
("TestServletContextListener"의 "constructor" 실행)
ServletContext 초기화 실행
("TestServletContextListener"의 "contextInitialized" 실행)

"Servers"탭에서 "Tomcat8"를 선택하고 "stop"버튼(stop the server)을 클릭합니다.

 

참고로, "Tomcat"에서 "stop"버튼(stop the server)을 클릭하면 "contextDestroyed"에 적용된 메시지가 나타나지 않습니다. 그렇지만 내부적으로 정상적으로 동작됩니다.

만약, 이클립스에서 "contextDestroyed"에 적용된 메시지를 확인하고 싶으시면 "contextDestroyed"에서 간단하게 스페이스를 추가하여 저장하시면 reload로면서 "contextDestroyed"에서 적용된 메시지가 나타날 겁니다.

"Tomcat"의 "config"의 "server.xml"의 "Context"에 "reloadable=true"이 설정되어 있어야 합니다.

 

반응형

3. "test2" 프로젝트의 "Java Resources"에서 "src/main/java"의 "com.hom.project.test2.listener"에서 오른쪽 버튼을 클릭하여 컨텍스트 메뉴 [New > Listener]를 클릭합니다.

"Create Listener"창의 "Class name"에 "TestServletContextAttributeListener"를 입력합니다.

"Next >"버튼을 클릭합니다.

"Servlet context events"의 "Changes to attributes"를 체크합니다.

"Finish"버튼을 클릭합니다.

"TestServletContextAttributeListener.java"파일이 생성됩니다.

 

"TestServletContextAttributeListener.java"의 "constructor"와 "attributeAdded", "attributeRemoved", "attributeReplaced"에 출력문을 코딩하여 어느 시점에서 호출되는 지를 확인해하기 위해서입니다.

public TestServletContextAttributeListener() {
	System.out.println("ServletContextAttributeListener 생성자 실행");
}

public void attributeAdded(ServletContextAttributeEvent event)  { 
	System.out.println("servletContext에 속성 추가 - 속성명 : " + event.getName() + ", 속성 값 : " + event.getValue());
}

public void attributeRemoved(ServletContextAttributeEvent event)  { 
	System.out.println("servletContext에 속성 삭제 - 속성명 : " + event.getName() + ", 속성 값 : " + event.getValue());
}

public void attributeReplaced(ServletContextAttributeEvent event)  { 
	System.out.println("servletContext에 속성 변경 - 속성명 : " + event.getName() + ", 속성 값 : " + event.getValue());
}

 

4. "TestDispatcherServlet.java"의 "service"에 "ServletContext"의 속성을 변경하여 이벤트가 발생하도록 코딩합니다.

ServletContext servletContext = request.getServletContext();
servletContext.setAttribute("httpServletInfo", "TestDispatcherServlet");
servletContext.setAttribute("httpServletInfo", "TestDispatcherServlet2");
servletContext.removeAttribute("httpServletInfo");

"setAttribute"으로 속성을 설정할 경우, 이전에 속성이 없으면 추가되고 있으면 속성의 값을 변경하여 처리됩니다.

 

5. "Servers"탭에서 "Tomcat8"를 선택하고 "start"버튼(start the server)을 클릭하고 "Console"탭을 클릭합니다.

[Console]

ServletContextListener 생성자 실행
ServletContextAttributeListener 생성자 실행 - 추가된 리스너 생성자
("TestServletContextAttributeListener"의 "constructor" 실행)
ServletContext 초기화 실행

 

6. 웹 브라우저에서 "http://localhost:8080/test2/test1.do"를 입력합니다.

"Console"탭을 클릭합니다.

[Console]

Apply Request Encoding
(서블릿 필터1(TestEncodingFilter) - 요청에 인코딩 적용)

예외처리된 URL입니다.
(서블릿 필터2(TestSecurityFilter) - 인증이 필요없는 URL이라 필터 통과 처리)

servletContext에 속성 추가 - 속성명 : httpServletInfo, 속성 값 : TestDispatcherServlet
(서블릿(TestDispatcherServlet)의 "service"에서 서블릿 켄텍스트(servletContext)에 "httpServletInfo" 속성을 추가)

servletContext에 속성 변경 - 속성명 : httpServletInfo, 속성 값 : TestDispatcherServlet
(서블릿(TestDispatcherServlet)의 "service"에서 서블릿 켄텍스트(servletContext)에 "httpServletInfo" 속성을 변경)

servletContext에 속성 삭제 - 속성명 : httpServletInfo, 속성 값 : TestDispatcherServlet2
(서블릿(TestDispatcherServlet)의 "service"에서 서블릿 켄텍스트(servletContext)에 "httpServletInfo" 속성을 삭제)

contextPath : /test2
requestURI : /test2/test1.do
changed requestURI : /test1.do
(서블릿(TestDispatcherServlet)의 "service"에서 URL 처리)

servletContext에 속성 추가 - 속성명 : org.apache.jasper.runtime.JspApplicationContextImpl, 속성 값 : org.apache.jasper.runtime.JspApplicationContextImpl@502de59d
(서블릿 켄텍스트(servletContext)에 JSP 처리를 위한 객체을 속성에 추가)

Apply Response Encoding
(서블릿 필터 - 요청에 인코딩 적용)

 

참고로, "ServletContextAttributeListener의 "attributeReplaced"는 "ServletContextAttributeEvent"의 변경된 속성 객체가 아닌 변경 전 속성 객체를 전달하는 것을 확인할 수 있습니다.

728x90
반응형