Listener.jsp (로그인 및 로그아웃 상태 표시)

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%
    // 현재 클라이언트 세션 username 가져오기
    String username = (String) session.getAttribute("username");
%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>3.Listener</title>
</head>
<body>
    <h3>3.리스너(Listener)</h3>

    <% if(username == null){ %>
        <h4>로그인</h4>
        <form action="/ch09/login.do" method="post">
            <input type="text" name="uid"><br>
            <input type="password" name="pass"><br>
            <input type="submit" value="로그인">
        </form>
    <% } else { %>
        <h4>로그인 성공</h4>
        <p>
            <%= username %>님 반갑습니다.<br>
            <a href="/ch09/logout.do">로그아웃</a>
        </p>
    <% } %>
</body>
</html>

로그인 서블릿

사용자가 입력한 아이디와 비밀번호를 검증하고, 성공적으로 로그인하면 세션에 username 속성을 저장합니다.

package servlet;

import java.io.IOException;
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;

@WebServlet("/login.do")
public class Login extends HttpServlet {

    private static final long serialVersionUID = 129509529672956551L;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 데이터 수신
        String uid = req.getParameter("uid");
        String pass = req.getParameter("pass");

        // 아이디 abc123, 비밀번호 1234 확인
        if(uid.equals("abc123") && pass.equals("1234")) {

            // 현재 클라이언트 세션 가져오기
            HttpSession session = req.getSession();

            // 로그인 세션 처리 (세션에 username 속성 추가)
            session.setAttribute("username", uid);

            // 로그인 후, 리다이렉트
            resp.sendRedirect("/ch09/3.Listener.jsp");

        } else {

            // 로그인 실패 시 리다이렉트
            resp.sendRedirect("/ch09/3.Listener.jsp?login=100");
        }
    }
}

로그아웃 서블릿

로그아웃 시 세션을 무효화(invalidate())하고, 이후 /ch09/3.Listener.jsp로 리다이렉트

package servlet;

import java.io.IOException;
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;

@WebServlet("/logout.do")
public class Logout extends HttpServlet {

    private static final long serialVersionUID = 232424321L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 현재 클라이언트 세션 정보 해제
        HttpSession session = req.getSession();
        session.invalidate();

        // 로그아웃 후, 리다이렉트
        resp.sendRedirect("/ch09/3.Listener.jsp");
    }
}

SessionListener 클래스

package listener;

import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionAttributeListener;
import jakarta.servlet.http.HttpSessionBindingEvent;

@WebListener
public class SessionListener implements HttpSessionAttributeListener {

    // 로그인 사용자 수를 추적하는 변수
    int count = 0;

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        // 세션에 값이 추가될 때 (예: 사용자 로그인 시)
        if ("username".equals(event.getName())) { // 세션에 "username" 속성이 추가될 때
            count++;
            System.out.println("현재 로그인 총 사용자 : " + count);
        }
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        // 세션에 값이 제거될 때 (예: 사용자 로그아웃 시)
        if ("username".equals(event.getName())) { // 세션에서 "username" 속성이 제거될 때
            count--;
            System.out.println("현재 로그인 총 사용자 : " + count);
        }
    }
}