클라이언트에서 요청이 와야 servlet / jsp 가 실행되는데, 요청이 오기 전에 어떤 작업을 미리 하고싶다면
→ Servlet Context Listener
application 이 실행될 때 Servlet Context Listener 가 가지고있는 특정 메소드를 실행시킴
어떤 servlet / jsp 보다 먼저 실행된다는 보장이 있음
어플리케이션을 실행하면 실행됨
필터는 요청이 와야 실행되지만 리스너는 요청과 무관 (경로지정도 하지 않음)
교재 20chapter
listener01 패키지 생성 - 패키지 우클릭 - new - Listener 생성
Class name: AppListener01
Lifecycle 선택
다음과 같이 작성된 채로 생성됨
package listener01;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AppListener01
*
*/
@WebListener
public class AppListener01 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener01() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
@WebListener 붙어있으면 tomcat이 확인하여 적절히 실행시켜줌
AppListener01 implements ServletContextListener
- ServletContextListener 인터페이스를 구현하도록 만듦
메소드
1)contextDestroyed : tomcat 에 의해 종료될 때 실행됨
- web application 종료 직전에 실행되는 메소드
- 해당 web application 종료 전에 실행해야 할 작업을 명시하여 이용할 수 있음 (ex. 백업)
2)contextInitialized : tomcat 에 의해 실행 되자마자 (준비가 되자마자) 실행됨
- web application 시작 시 한번 생성되는 ServletContext 생성 직후 호출되어 실행됨
- 해당 web application 초기화 관련 작업에 이용할 수 있음
AppListener01
package listener01;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AppListener01
*
*/
@WebListener
public class AppListener01 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener01() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 종료됨!! 리스너1 작동!!!!");
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 실행됨. 리스너1 작동!!!!");
}
}
contextDestroyed 메소드 안에 "어플리케이션 종료됨!! 리스너1 작동!!!!" 출력되도록 작성
contextInitialized 메소드 안에 "어플리케이션 실행됨. 리스너1 작동!!!!" 출력되도록 작성
server (tomcat) 를 restart 하여 로그가 출력되는지 확인 (요청없이 서버 시작만 해도 실행됨) / 종료할 때는 역순
AppListener02
package listener01;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AppListener02
*
*/
@WebListener
public class AppListener02 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener02() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 종료됨!!! 리스너2 일함!!!!!");
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 실행됨!! 리스너2 일함!!!!!!!");
}
}
1, 2 둘다 실행됨~!
AppListener03
package listener01;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AppListener03
*
*/
// @WebListener
public class AppListener03 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener03() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 종료됨!! 리스너 3번 동작!!");
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("어플리케이션 실행됨!! 리스너3번 동작!!!");
}
}
이번에는 web.xml 을 이용하여 listener 등록해보기
web.xml 사용하려면 @WebListener 주석처리 해야 함 (삭제)
* contextInitialized() 메소드는 등록된 순서대로 실행됨 ↔ contextDestroyed() 메소드는 등록된 반대 순서로 실행됨
web.xml
<listener>
<listener-class>listener01.AppListener03</listener-class>
</listener>
(필터와는 다르게 이렇게 간단히 작성) 패키지명.Listener이름
* web.xml 의 listener 가 웹어노테이션보다 빨리 실행됨 (웹어노테이션의 순서는 보장되지 않음)
AppListener04
package listener01;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AppListener04
*
*/
// @WebListener
public class AppListener04 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener04() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("애플리케이션 종료됨! 4번 리스너 실행");
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("애플리케이션 실행됨!4번 리스너 실행");
}
}
server (tomcat) 을 restart 해서 로그가 출력되는지 확인
web.xml 사용
<listener>
<listener-class>listener01.AppListener03</listener-class>
</listener>
<listener>
<listener-class>listener01.AppListener04</listener-class>
</listener>
1: @WebListener
2: @WebListener
3: web.xml - 첫번째로 작성
4: web.xml - 두번째로 작성
실행 시, 3 - 4 - 1 - 2
종료 시 (역순), 2 - 1 - 4 - 3
AppListener05
package listener01;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Application Lifecycle Listener implementation class AppListener05
*
*/
// @WebListener
public class AppListener05 implements ServletContextListener {
/**
* Default constructor.
*/
public AppListener05() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
ServletContext application = sce.getServletContext();
application.setAttribute("appAttr1", "appVal1");
application.setAttribute("appAttr2", "appVal2");
// context path를 application attribute에 추가
String contextPath = application.getContextPath();
application.setAttribute("appRoot", contextPath);
}
}
contextInitialized 메소드에 코드 작성
application.setAttribute 로
appVal1 은 appAttr1 에 저장, appVal2 는 appAttr2 에 저장하여 전달
// context path 를 application attribute 에 추가
application.getContextPath() 로 전달받아서 문자열 contextPath 에 저장
application.setAttribute 로 방금 받은 contextPath 를 appRoot 에 저장
01listener.jsp
이번엔 webapp > WEB-INF > view 폴더 말고 그냥 webapp 폴더 안에
15listener 폴더 만들고 01listener.jsp 파일 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
\${appAttr1 } : ${appAttr1 } <br>
\${appAttr2 } : ${appAttr2 } <br>
<%-- appAttr2 attribute를 application 영역에 추가하는 코드를
AppListener05의 contextInitialized 메소드에 작성
--%>
<hr>
\${pageCotext.request.contextPath } : ${pageContext.request.contextPath } <br>
\${appRoot } : ${appRoot } <br>
<%= request.getContextPath() %> <br>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
( \ 백슬래시 쓰면 el 적용 안된다고 했던 것 같은데.. )
아무튼 ${appAttr1 }, ${appAttr2 }, ${pageContext.request.contextPath }, ${appRoot } 출력
표현식으로 또 뭔가 전달받아서 출력
web.xml
<listener>
<listener-class>listener01.AppListener04</listener-class>
</listener>
<listener>
<listener-class>listener01.AppListener03</listener-class>
</listener>
<listener>
<listener-class>listener01.AppListener05</listener-class>
</listener>
★ 01listener.jsp 실행 시 이것이 요청되기 전에 (서버가 실행될 때), AppListener05 리스너의 contextInitialized 메소드가 실행됨
→ appVal1 은 appAttr1 에 저장, appVal2 는 appAttr2 에 저장하여 01listener.jsp 에서 el 로 사용가능했음
'course 2021 > JDBC\DB' 카테고리의 다른 글
DB02 - 22일(jdbc03~10) (0) | 2021.12.05 |
---|---|
DB01 - 19일(sql01~05, jdbc01~02) (0) | 2021.12.04 |
filter (0) | 2021.12.02 |
DB - aws, sql (0) | 2021.12.02 |
servlet03 - 07, 08, 09 (0) | 2021.12.02 |