HttpSessionBindingListener 리스너란
HttpSessionBindingListener는 HttpSessionBindingListener 리스너를 구현한 객체가 세션(HttpSession) 객체의 setAttribute() 메서드를 통해 바인딩되거나 removeAttribute() 메서드를 통해 언바인딩될 때에 대한 이벤트를 처리할 수 있도록 하는 리스너입니다.
public interface HttpSessionBindingListener extends EventListener {
/**
* 구현 객체가 세션에 바인딩 될때 호출됨
*/
public void valueBound(HttpSessionBindingEvent event);
/**
* 구현 객체가 세션에서 언바인딩(제거) 될때 호출
*/
public void valueUnbound(HttpSessionBindingEvent event);
} |
cs |
HttpSessionBindingEvent 객체
HttpSessionBindingListener인터페이스의 메서드를 보면 HttpSessionBindingEvent 객체가 매개변수로 넘어오는것을 볼 수 있습니다. 이 이벤트객체는 자신이 바인딩되거나 언바인딩된 대상 세션(HttpSession)객체를 얻을 수 있는 메서드와 어떤 속성명(Attribute Name)으로 바인딩 또는 언바인딩되어있는지 등을 얻을 수 있는 메서드가 있습니다.
HttpSessionBindingListener 구현 예제
리스너를 구현해보고 동작하는 예제를 테스트해보도록 하겠습니다.
login.html
기본적인 login 페이지입니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<form action="login" method="post">
id : <input type="text" name="id"><br>
password : <input type="password" name="password"><br>
<input type="submit" value="로그인">
</form>
</body>
</html> |
cs |
HttpSessionBindingListener 구현한 UserInfo.java 작성
UserInfo 클래스는 로그인한 사용자의 정보를 담는 용도이며 HttpSessionBindingListener를 구현하였습니다. 세션에 바인딩되거나 언바인되는 시점에 콘솔에 로그를 출력하도록 하였습니다.
package listener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class UserInfo implements HttpSessionBindingListener {
String id;
String password;
// 기본 생성자가 꼭 있어햐 함
public UserInfo() {
}
public UserInfo(String id, String password) {
this.id = id;
this.password = password;
}
public String getId() {
return id;
}
@Override
public void valueBound(HttpSessionBindingEvent hsbe) {
System.out.println("UserInfo 객체가 세션에 바인딩됨");
}
@Override
public void valueUnbound(HttpSessionBindingEvent hsbe) {
System.out.println("UserInfo 객체가 세션에서 언바인딩(제거됨)");
}
} |
cs |
구현한 리스너 등록
특이사항으로 HttpSessionBindingListener는 web.xml의 <listener> 태그나 @WebListener 어노테이션을 통해 리스너 등록 설정을 해주지 않는다는 점 입니다. 다른 리스너는 리스너 등록 설정을 하고 서블릿 컨테이너가 web.xml의 리스너 등록 설정을 읽어 기동되는 시점에 생성되고 특정 이벤트마다 호출되어 사용되는 구조입니다.
그러나 HttpSessionBindingListener의 경우 리스너를 구현한 클래스의 인스턴스를 원하는 시점마다 new 연산자를 통해 직접 생성하고 세션에 바인딩되거나 언바인딩 되는 시점에 메서드를 호출하기에 따로 등록이 필요 없습니다.
LoginServlet 작성
다음은 로그인 서블릿입니다.
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import listener.UserInfo;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String id = request.getParameter("id");
String password = request.getParameter("password");
if(id.equals(password)) {
HttpSession session = request.getSession();
UserInfo userInfo = new UserInfo(id, password); //구현한 리스너를 세션에 바인딩
session.setAttribute("userInfo", userInfo);
}else {
response.sendRedirect("login.html");
}
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println(" <h1>로그인됨</h1>");
out.println(" <a href='logout.jsp'>로그아웃</a>");
out.println("</body>");
out.println("</html>");
}
} |
cs |
login.html에서 id와 password를 같은값으로 입력하면 로그인 된것으로 처리하고 방금전 구현했던 리스너 클래스인 UserInfo 클래스의 인스턴스를 id와 password를 넣어 생성합니다.
그리고 session.setAttribute("userInfo", userInfo)를 호출하는데, 이 행위가 바인딩입니다. 이때 valueBound()가 호출되는것입니다. 이후 로그인되었다는 결과 페이지를 브라우저로 출력합니다.
logout.jsp 작성
세션을 invalidate()메서드를 통해 제거하고 로그아웃되었다는 결과를 보여줍니다. invalidate()가 호출되어 세션이 종료되었다는것은 세션으로부터 UserInfo가 언바운드 되었다는것입니다. 즉 이때 valueUnbound()가 호출됩니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="listener.UserInfo"%>
<html>
<head>
<title>로그아웃</title>
</head>
<body>
<%
UserInfo userInfo = (UserInfo)session.getAttribute("userInfo");
String id = userInfo.getId();
session.invalidate();
%>
<h1><%= id %> 로그아웃됨 </h1>
</body>
</html> |
cs |
테스트
login.html로 이동 후 id와 비밀번호를 같은값으로 입력하고 로그인 버튼을 클릭합니다.
LoginServlet(/login)에게 요청이 전달되고 로그인 되었다는 결과가 보입니다. LoginServlet에서 세션에 UserInfo가 바인딩되었는지 콘솔을 통해 확인합니다.
잘 바인딩 되었다는것을 알 수 있습니다.
이번에는 로그아웃 버튼을 클릭해 logout.jsp를 호출해봅니다.
언바인딩 되었다는 로그가 출력되는군요.
다음글
'Servlet&Jsp' 카테고리의 다른 글
[서블릿/JSP] ServletRequestListener 리스너로 ServletRequest 생성 소멸시 이벤트 처리하기 (0) | 2019.07.15 |
---|---|
[서블릿/JSP] HttpSessionBindingListener의 바운드와 언바운드 조건 (0) | 2019.07.15 |
[서블릿/JSP] 톰캣 8.0 이하에서 HTTP Response 메시지에서 Server 값 바꾸기 (0) | 2019.07.10 |
[서블릿/JSP] 서버의 세션 수 제한하는 방법 (0) | 2019.07.09 |
[서블릿/JSP] 세션 timeout 설정 방법들과 적용 우선순위 (0) | 2019.07.09 |