서블릿에서 발생하는 이벤트를 처리할 수 있도록 제공하는 리스너
서블릿 관련 Listener | 추상 메서드 | 기능 |
---|---|---|
ServletContextAttributeListener | attributeAdded() attributeRemoved() attributeReplaced() | Context객체에 속성 추가/제거/수정 이벤트 발생 시 처리 |
HttpSessionListener | sessionCreated() sessionDestroyed() | 세션 객체의 생성/소멸 이벤트 발생 시 처리 |
ServletRequestListener | reqeustInitialized() requestDestroyed() | 클라이언트의 요청 이벤트 발생 시 처리 |
ServletRequestAttributeListener | attributeAdded() attributeRemoved() attributeReplaced() | 요청 객체에 속성 추가/제거/수정 이벤트 발생 시 처리 |
HttpSessionBiningListener | valueBound() valueUnbound() | 세션에 바인딩/언바인딩된 객체를 알려주는 이벤트 발생 시 처리 |
HttpSessionAttributeListener | attributeAdded() attributeRemoved() attributeReplaced() | 세션에 속성 추가/제거/수정 이벤트 발생 시 처리 |
ServletContextListener | contextInitialized() contextDestroyed() | 컨텍스트 객체의 생성/소멸 이벤트 발생 시 처리 |
HttpSessionActivationListener | sessionDidActivate() sessionWillPassivate() | 세션의 활성/비활성 이벤트 발생 시 처리 |
HttpSessionBindingListener를 제외한 모든 Listener는 @WebListener를 사용해서 Listener로 등록해야 한다.
접속자 수와 접속자 아이디를 집계해 화면에 띄우는 예제다.
controll + space -> Listener 생성
구현할 인터페이스를 고르면 된다.
LoginImpl.java
@WebListener
public class LoginImpl implements HttpSessionListener {
String id;
String pwd;
static int totalUser = 0;
public LoginImpl() {}
public LoginImpl(String id, String pwd) {
this.id = id;
this.pwd = pwd;
}
public void sessionCreated(HttpSessionEvent se) {
System.out.println("세션 생성");
++totalUser;
}
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("세션 소멸");
--totalUser;
}
}
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form name="login" method="post" action="/listenerLogin">
아이디 : <input type="text" name="id"><br>
비밀번호:<input type="password" name="password">
<button>확인</button>
</form>
</body>
</html>
LoginTest.java
@WebServlet("/listenerLogin")
public class LoginTest extends HttpServlet {
ServletContext context;
//로그인한 접속자 ID를 저장할 List
List<String> userList = new ArrayList<>();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
context = getServletContext();
String id = request.getParameter("id");
String pwd = request.getParameter("password");
//로그인한 아이디와 비밀번호로 LoginImpl객체 생성
LoginImpl loginUser = new LoginImpl(id, pwd);
/* 최초 로그인 시, ID를 List에 저장하고, context객체에 바인딩한다. */
if (session.isNew()) { // 새로 생성된 세션일 경우
session.setAttribute("loginUser", loginUser);
userList.add(id);
context.setAttribute("userList", userList);
}
out.print("<html><head></head><body><h1>ID : " + id + "<br>PW : " + pwd + "<br>접속자 수 : " + LoginImpl.totalUser+"</h1>"
+"<h2>접속자 아이디 : <br>");
List list = (ArrayList)context.getAttribute("userList");
for(int i=0; i<list.size();i++) {
out.print(list.get(i)+"<br>");
}
out.println("<a href='/listenerLogout?id="+id+"'>로그아웃</a>");
//JS의 setTimeout함수를 이용하여 5초마다 서블릿에 재요청하며 현재 접속자수를 파악
out.print("<script type='text/javascript'> setTimeout('history.go(0);',5000); </script></body></html>");
}
}
LogoutTest.java
@WebServlet("/listenerLogin")
public class LoginTest extends HttpServlet {
ServletContext context;
//로그인한 접속자 ID를 저장할 List
List<String> userList = new ArrayList<>();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
context = getServletContext();
String id = request.getParameter("id");
String pwd = request.getParameter("password");
//로그인한 아이디와 비밀번호로 LoginImpl객체 생성
LoginImpl loginUser = new LoginImpl(id, pwd);
/* 최초 로그인 시, ID를 List에 저장하고, context객체에 바인딩한다. */
if (session.isNew()) { // 새로 생성된 세션일 경우
session.setAttribute("loginUser", loginUser);
System.out.println("id : " + id );
userList.add(id);
System.out.println("userList : " + userList);
context.setAttribute("userList", userList);
}
out.print("<html><head></head><body><h1>ID : " + id + "<br>PW : " + pwd + "<br>접속자 수 : " + LoginImpl.totalUser+"</h1>"
+"<h2>접속자 아이디 : <br>");
List list = (ArrayList)context.getAttribute("userList");
for(int i=0; i<list.size();i++) {
out.print(list.get(i)+"<br>");
}
out.println("<a href='/listenerLogout?id="+id+"'>로그아웃</a>");
//JS의 setTimeout함수를 이용하여 5초마다 서블릿에 재요청하며 현재 접속자수를 파악
out.print("<script type='text/javascript'> setTimeout('history.go(0);',5000); </script></body></html>");
}
}
크롬에서 로그인 시 나타나는 화면
Edge에서 로그인 시 나타나는 화면
크롬 화면도 setTimeout()에 의해서 자동 갱신된다.
크롬에서 로그아웃 시 로그인 중인 브라우저 화면이 자동 갱신된다.