프로그래밍 언어/자바 웹

HttpSessionListener 이용해 로그인 접속자수 표시

· 코딩마이데이

1. 다음과 같이 실습 파일을 준비합니다.

실습 파일 위치

 

 

2. 첫 번째 서블릿인 LoginTest 클래스 파일을 다음과 같이 수정합니다. setAttribute()를 이용해 loginUser를 세션에 바인딩하면 LoginImpl 클래스에 구현된 이벤트 핸들러를 이용해 접속자수를 1 증가시킵니다. 그리고 user_list에 접속에 ID를 저장한 다음 ServletContext 객체에 바인딩합니다.

package sec04.ex02;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/login")
public class LoginTest extends HttpServlet {
	ServletContext context = null;
	List user_list = new ArrayList();
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		context = getServletContext();
		PrintWriter out = response.getWriter();
		HttpSession session = request.getSession();
		String user_id = request.getParameter("user_id");
		String user_pw = request.getParameter("user_pw");
		
		LoginImpl loginUser = new LoginImpl(user_id, user_pw);
		if (session.isNew()) {
			session.setAttribute("loginUser", loginUser);
			user_list.add(user_id);
			context.setAttribute("user_list", user_list);
		}
		
		out.println("<html><body>");
		out.println("아이디는 " + loginUser.user_id + "<br>");
		out.println("총 접속자수는" + LoginImpl.total_user + "<br><br>");
		out.println("접속 아이디:<br>");
		List list = (ArrayList) context.getAttribute("user_list");
		for (int i = 0; i < list.size(); i++) {
			out.println(list.get(i) + "<br>");
		}
		out.println("<a href='logout?user_id=" + user_id + "'>로그아웃 </a>");
		out.println("</body></html>");
	}
}

 

3. LogoutTest 클래스를 다음과 같이 작성합니다. 여기서는 로그아웃 링크를 클릭하면 접속자 수를 1 감소시키고 user_list에서 로그아웃한 접속자 ID를 삭제한 후 다시 user_list에서 ServletContext 객체에 바인딩하도록 설정합니다.

package sec04.ex02;

import jakarta.servlet.Servlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;


@WebServlet("/logout")
public class LogoutTest extends HttpServlet {
	ServletContext context;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;chatset=utf-8");
		PrintWriter out = response.getWriter();
		HttpSession session = request.getSession();
		String user_id = request.getParameter("user_id");
		session.invalidate();
		List user_list = (ArrayList) context.getAttribute("user_list");
		user_list.remove(user_id);
		context.removeAttribute("user_list");
		context.setAttribute("user_list", user_list);
		out.println("<br>로그아웃했습니다.");
	}
}

 

LoginImpl 클래스는 HttpSessionListener를 구현해 세션 생성과 소멸 시 이벤트를 처리하는 핸들러입니다. 중요한 것은 앞의 LoginImpl에서 구현한 HttpSessionBindingListener와는 다르게 HttpSessionListener는 반드시 리스너를 구현한 이벤트 핸들러를 애너테이션을 이용해서 등록해야 한다는 것입니다.

 

1. sec04.ex02 패키지를 선택하고 마우스 오른쪽 버튼을 클릭한 후 New > Listener를 선택합니다.

New > Listener 선택

 

2. Class name으로 LoginImpl을 입력하고 Next를 클릭합니다.

Class name으로 LoginImpl 입력 후 Next 클릭

 

3. HttpSessionListener에 체크하고 Next를 클릭합니다.

HttpSessionListener 선택 후 Next 클릭

 

5. Finish를 클릭합니다.

Finish 클릭

 

5. @WebListener 애너테이션으로 리스너가 등록된 것을 확인할 수 있습니다.

애너테이션으로 리스너 등록 확인

 

6. 리스너를 등록한 이벤트 핸들러를 이용해서 세션을 생성할 때는 sessionCreated() 메서드로 이벤트를 처리하고, 세션을 삭제할 때는 sessionDestroyed() 메서드로 이벤트를 처리합니다.

package sec04.ex02;

import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;

@WebListener
public class LoginImpl implements HttpSessionListener {
    String user_id;
    String user_pw;
    static int total_user = 0;
    
    public LoginImpl() {
    }
    
    public LoginImpl(String user_id, String user_pw) {
    	this.user_id = user_id;
    	this.user_pw = user_pw;
    }
    
    @Override
    public void sessionCreated(HttpSessionEvent arg0) {
    	System.out.println("세션 생성");
    	++total_user;
    }

	@Override
    public void sessionDestroyed(HttpSessionEvent arg0)  { 
         System.out.println("세션 소멸");
         --total_user;
    }
}

 

7. 실행하면 사용자마다 로그인/로그아웃 시 접속자 수와 접속자 ID를 표시해 줍니다. 다음은 첫번째 아이디로 로그인한 결과입니다.

크롬에서 로그인 시 결과

 

8. 이번에는 Microsoft Edge에서 두 번째 ID로 로그인하면 다음과 같이 현재 접속자수와 접속자 ID가 출력됩니다.

Microsoft Edge에서 로그인 시 결과

9. 다음 크롬에서 화면을 갱신하면 다음과 같이 현재 접속자수와 접속자 ID가 표시됩니다.

크롬에서 현재 접속자 정보 표

 

10. Microsoft Edge에서 로그아웃을 클릭합니다.

Microsoft Edge에서 로그아웃 클릭

 

11. 크롬에서 화면을 재요청하면 다음과 같이 현재 접속자수와 접속자 ID가 표시됩니다.

크롬 화면 재요청 시 접속자 정보 표시

 

'프로그래밍 언어 > 자바 웹' 카테고리의 다른 글

JSP의 3단계 작업 과정  (0) 2025.09.13
JSP 등장 배경  (1) 2025.09.10
여러 가지 서블릿 관련 Listener API  (0) 2025.09.04
Filter API  (1) 2025.09.01
서블릿의 여러 가지 URL 패턴  (0) 2025.08.29