Servlet-JSP

서블릿 리스너

voider 2020. 9. 11. 22:36

Servlet Listener API

서블릿에서 발생하는 이벤트를 처리할 수 있도록 제공하는 리스너

Listener의 메서드

서블릿 관련 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로 등록해야 한다.

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()에 의해서 자동 갱신된다.

크롬에서 로그아웃 시 로그인 중인 브라우저 화면이 자동 갱신된다.

'Servlet-JSP' 카테고리의 다른 글

액션 태그  (0) 2020.09.11
JSP😇  (0) 2020.09.11
Servlet Filter  (0) 2020.09.11
서블릿 스코프  (0) 2020.09.11
세션 로그인 예제  (0) 2020.09.10