2020년 12월 24일

업데이트:


프로젝트 구성

20201224_00

sql

20201224_02

라이브러리 설정




메인 화면

20201224_01


index.jsp

20201224_03

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
  <style>

      .bg-image-full {
        background: no-repeat center center scroll;
        -webkit-background-size: cover;
        -moz-background-size: cover;
        background-size: cover;
        -o-background-size: cover;
      }

      div.bg-image-full{
        height: 300px;
        text-align: center;
      }

      @font-face { font-family: 'GmarketSansBold'; src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/GmarketSansBold.woff') format('woff'); font-weight: normal; font-style: normal; }
      div.bg-image-full>h1{
        color : white;
        position: relative;
        top : 75px;
        font-size: 3em;
        font-family: 'GmarketSansBold';
        text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
      }
  </style>
</head>
<body>
	<!-- WEB-INF/views/common/header.jsp 여기에 삽입(포함) -->
	<jsp:include page="WEB-INF/views/common/header.jsp"></jsp:include>
	<!-- 상대 경로로 작성함 -->
	
	<!-- 메인 화면 이미지 -->
	<div class="py-5 bg-image-full" style="background-image: url('https://iei.or.kr/resources/images/intro/intro_bg.jpg');">
	    <h1>Servlet/JSP<br>Web Application</h1>
	</div>
	
	<!-- 내용 작성 부분 -->
	<div class="py-5">
	  <div class="container">
	    <h1>Section Heading</h1>
	    <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
	    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid, suscipit, rerum quos facilis repellat architecto commodi officia atque nemo facere eum non illo voluptatem quae delectus odit vel itaque amet.</p>
	  </div>
	</div>
	
	<div class="py-5">
	  <div class="container">
	    <h1>Section Heading</h1>
	    <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
	    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid, suscipit, rerum quos facilis repellat architecto commodi officia atque nemo facere eum non illo voluptatem quae delectus odit vel itaque amet.</p>
	  </div>
	</div>
	
	<!-- WEB-INF/views/common/footer.jsp 여기에 삽입(포함) -->
	<jsp:include page="WEB-INF/views/common/footer.jsp"></jsp:include>
</body>
</html>



header.jsp

20201224_04

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>


<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>WebServer Project</title>

<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

<!-- Bootstrap core JS -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
     integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" 
     crossorigin="anonymous">
</script>

<!-- sweetalert : alert창을 꾸밀 수 있게 해주는 라이브러리 https://sweetalert.js.org/ -->
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

<style>
body {
	padding-top: 56px;
}
</style>
</head>
<body>
<!-- Navigation으로 된 header -->
<div class="header navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
    <div class="container">
        <a class="navbar-brand" href="${contextPath}">WebServer Project</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" 
            aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarResponsive">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item"><a class="nav-link" href="#">Notice</a></li>
                <li class="nav-item"><a class="nav-link" href="#">Board</a></li>

                <li class="nav-item active">
                    <a class="nav-link" data-toggle="modal" href="#modal-container-1">Login</a>
                </li>
            </ul>
        </div>
    </div>
</div>


<%-- Modal창에 해당하는 html 코드는 페이지 마지막에 작성하는게 좋다 --%>
<div class="modal fade" id="modal-container-1" role="dialog"
            aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="myModalLabel">로그인 모달창</h5>
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">×</span>
                </button>
            </div>

            <div class="modal-body">
                <form class="form-signin" method="POST" action="#">


                    <input type="text" class="form-control" id="memberId" 
                        name="memberId" placeholder="아이디" value="">
                    <br>
                    <input type="password" class="form-control" id="memberPwd"
                            name="memberPwd" placeholder="비밀번호">
                    <br>

                    <div class="checkbox mb-3">
                        <label> 
                            <input type="checkbox" name="save" id="save"> 아이디 저장
                        </label>
                    </div>

                    <button class="btn btn-lg btn-primary btn-block" type="submit">
                        로그인
                    </button>
                    <a class="btn btn-lg btn-secondary btn-block" href="#">
                        회원가입
                </a>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" 
                    data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>
</body>
</html>



footer.jsp

20201224_05

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<!-- Footer -->
	<div class="py-5 bg-dark footer">
	  <div class="container">
	    <p class="m-0 text-center text-white">Copyright &copy; KH Information Educational Institute A-Class</p>
	  </div>
	</div>
</body>
</html>



include

  • index.jsp body 부분에 작성
<!-- body 내 상단에 작성-->
<jsp:include page="WEB-INF/views/common/header.jsp"></jsp:include>

<!-- 생략 -->

<!-- body 내 하단에 작성 -->
<jsp:include page="WEB-INF/views/common/header.jsp"></jsp:include>



로고 클릭 시 메인 페이지로 이동

20201224_06

  • header.jsp body 부분에 작성

<!--
     프로젝트의 시작주소(Context root)를 얻어와 간단하게 
     사용할 수 있도록 contextPath라는 변수 생성
-->
<c:set var="contextPath" scope="application" 
    value="${pageContext.servletContext.contextPath}"/>


<!-- 로고 <a> 태그 href 부분 수정-->
<a class="navbar-brand" href="${contextPath}">WebServer Project</a>


20201224_07



로그인

  • 로그인 전 헤더
    20201224_08

  • 로그인 모달창
    20201224_09

  • 로그인 후 헤더
    20201224_10

  • 로그인 실패 경고창
    20201224_12


web.xml

  <resource-ref>
    <description>Oracle Datasource</description>
    <res-ref-name>jdbc/oracle</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>



context.xml (DBCP)

  • context.xml 경로
    20201224_11

  • context.xml 하단 부분에 작성

<!-- 생략 -->

<!-- DataBase Connection Pool -->
<Resource 
    name="jdbc/oracle" 
    auth="Container" 
    type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.OracleDriver"
    url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
    username="server"
    password="server"
    maxTotal="20"
    maxIdle="10"
    maxWaitMillis="-1"
/>

<!--
    name : JNDI 이름 Context의 lookup()을 사용하여 자원을 찾을 때 사용한다.
            java:comp/env 디렉터리에서 찾을 수 있음.
    auth : 자원 관리 주체 지정(Application 또는 Container)
    type : Resourtece의 타입을 지정한다.
    driverClassName : JDBC 드라이버 클래스 이름
    maxTotal : DataSource에서 유지할 수 있는 최대 커넥션의 수
    maxIdle : 사용되지 않고 풀에 저장될 수 있는 최대 커넥션의 개수.
              음수일 경우 제한이 없다.
    maxWaitMillis : 커넥션 반납을 기다리는 시간
                    (-1은 반환될 때까지 기다린다.) 
 -->



JDBCTemlate.java

public class JDBCTemplate {
    private static Connection conn = null;
    private JDBCTemplate(){}

    /* 
        WAS(Tomcat)가 미리 DB에 접속할 수 있는 객체(Connection)를 일정 개수를
        만들어 두고 요청이 올 때마다 만들어 둔 객체를 전달하고 사용 완료 후에는
        반환 받는 Connection Pool 사용
   
    */

    public static Connection getConnection() 
            throws NamingException, SQLException{
        // JNDI(Java Naming and Directory Interface API)
        /* 
            디렉터리 서비스에 접근하는데 사용하는 API
            애플리케이션은 JNDI를 사용하여 서버의 resource를 찾음.
            특히 JDBC resouce를 data source라고 부름.

            Resource를 서버에 등록할 때 고유한 JNDI 이름을 붙이는데,
            JNDI 이름은 디렉터리 경로 형태를 갖는다.
            ex) jdbc/mydb

            서버에서 'jdbc/oracle'이라는 DataSource를 찾으려면
            'java:comp/env/jdbc/oracle'이라는 JNDI 이름으로 찾아야함.
            즉 lookup() 메소드에 'java:comp/env/jdbc/oracle'를 인자값으로 넘긴다.
        */

        // Servers에 존재하는 context.xml 파일을 찾는 작업
        Context initContext = new InitialContext();
        Context envContext = (Context)initContext.lookup("java:/comp.env");        

        // context.xml 파일에서 name이 "jdbc/oracle"인 DataSource를 얻어옴
        // DataSource : DriverManager를 대체하는 객체로 Connection 생성, Connection pool을 구현하는 객체

        DataSource ds = (DataSource)envContext.lookup("jdbc/oracle");

        conn = ds.getConnection(); // DataSource에 의해 미리 만들어진 Connection 중 하나

        conn.setAutoCommit(false);

        return conn;
    }

	public static void commit(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) {
				conn.commit();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void rollback(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) {
				conn.rollback();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// DB 연결 자원 반환 구문도 static으로 작성
	public static void close(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) {
				conn.close();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void close(ResultSet rset) {
		try {
			if(rset != null && !rset.isClosed()) {
				rset.close();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void close(Statement stmt) {
		try {
			if(stmt != null && !stmt.isClosed()) {
				stmt.close();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}



Member.java

public class Member {
	private int memberNo; // 회원번호
	private String memberId; // 아이디
	private String memberPwd; // 비밀번호
	private String memberName; // 이름
	private String memberPhone; // 전화번호
	private String memberEmail; //이메일
	private String memberAddress; //주소
	private String memberInterest; // 관심분야
	private Date memberEnrollDate; // 가입일
	private String memberStatus; // 상태
	private String memberGrade; //등급
	
	public Member() { }
	
	

	public Member(int memberNo, String memberId, String memberName, String memberPhone, String memberEmail,
			String memberAddress, String memberInterest, String memberGrade) {
		super();
		this.memberNo = memberNo;
		this.memberId = memberId;
		this.memberName = memberName;
		this.memberPhone = memberPhone;
		this.memberEmail = memberEmail;
		this.memberAddress = memberAddress;
		this.memberInterest = memberInterest;
		this.memberGrade = memberGrade;
	}



	public Member(int memberNo, String memberId, String memberPwd, String memberName, String memberPhone,
			String memberEmail, String memberAddress, String memberInterest, Date memberEnrollDate, String memberStatus,
			String memberGrade) {
		super();
		this.memberNo = memberNo;
		this.memberId = memberId;
		this.memberPwd = memberPwd;
		this.memberName = memberName;
		this.memberPhone = memberPhone;
		this.memberEmail = memberEmail;
		this.memberAddress = memberAddress;
		this.memberInterest = memberInterest;
		this.memberEnrollDate = memberEnrollDate;
		this.memberStatus = memberStatus;
		this.memberGrade = memberGrade;
	}

	public int getMemberNo() {
		return memberNo;
	}

	public void setMemberNo(int memberNo) {
		this.memberNo = memberNo;
	}

	public String getMemberId() {
		return memberId;
	}

	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}

	public String getMemberPwd() {
		return memberPwd;
	}

	public void setMemberPwd(String memberPwd) {
		this.memberPwd = memberPwd;
	}

	public String getMemberName() {
		return memberName;
	}

	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}

	public String getMemberPhone() {
		return memberPhone;
	}

	public void setMemberPhone(String memberPhone) {
		this.memberPhone = memberPhone;
	}

	public String getMemberEmail() {
		return memberEmail;
	}

	public void setMemberEmail(String memberEmail) {
		this.memberEmail = memberEmail;
	}

	public String getMemberAddress() {
		return memberAddress;
	}

	public void setMemberAddress(String memberAddress) {
		this.memberAddress = memberAddress;
	}

	public String getMemberInterest() {
		return memberInterest;
	}

	public void setMemberInterest(String memberInterest) {
		this.memberInterest = memberInterest;
	}

	public Date getMemberEnrollDate() {
		return memberEnrollDate;
	}

	public void setMemberEnrollDate(Date memberEnrollDate) {
		this.memberEnrollDate = memberEnrollDate;
	}

	public String getMemberStatus() {
		return memberStatus;
	}

	public void setMemberStatus(String memberStatus) {
		this.memberStatus = memberStatus;
	}

	public String getMemberGrade() {
		return memberGrade;
	}

	public void setMemberGrade(String memberGrade) {
		this.memberGrade = memberGrade;
	}

	@Override
	public String toString() {
		return "Member [memberNo=" + memberNo + ", memberId=" + memberId + ", memberPwd=" + memberPwd + ", memberName="
				+ memberName + ", memberPhone=" + memberPhone + ", memberEmail=" + memberEmail + ", memberAddress="
				+ memberAddress + ", memberInterest=" + memberInterest + ", memberEnrollDate=" + memberEnrollDate
				+ ", memberStatus=" + memberStatus + ", memberGrade=" + memberGrade + "]";
	}
}



MemberService.java (service)

public class MemberService {
    private MemberDAO dao = new MemberDAO();

	/** 로그인 Service
	 * @param member
	 * @return loginMember
	 * @throws Exception
	 */
     public Member loginMember(Member member) throws Exception {
         Connection conn = getConnection();
         Member loginMember = dao.loginMember(conn, member);
         close(conn);
         return loginMember;
     }
}



member-query.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="loginMember">
SELECT MEMBER_NO, MEMBER_ID, MEMBER_NM, MEMBER_PHONE,
    MEMBER_EMAIL, MEMBER_ADDR, MEMBER_INTEREST,
    MEMBER_GRADE
FROM MEMBER
WHERE MEMBER_ID = ?
AND MEMBER_PWD = ?
AND MEMBER_STATUS = 'Y' 
</entry>
</properties>



MemberDAO.java

public class MemberDAO {

    // DAO에서 자주 사용되는 JDBC 참조 변수 선언
    private Statement stmt = null;
    private PreparedStatement pstmt = null;
    private ResultSet rset = null;
    private Properties prop = null;

    public MemberDAO() {
        // 외부에 저장된 XML 파일로부터 SQL을 얻어옴 ---> 유지보수성 향상

        try{
            String filePath = MemberDAO.class
                .getResource("/com/kh/wsp/sql/member/member-query.xml").getPath();
            
            prop = new Properties();
            prop.loadFromXML(new FileInputStream(filePath));
        }catch(Exception e){
            e.printStackTrace();
        }
    }

	/** 로그인 DAO
	 * @param conn
	 * @param member
	 * @return loginMember
	 * @throws Exception
	 */
    public Member loginMember(Connection conn, Member member) 
            throws Exception {

        // 결과 저장용 변수 선언
        Member loginMember = null;
        String query = prop.getProperty("loginMember");

        try{
            // 1) PreparedStatement 객체를 얻어와 query 세팅
            pstmt = conn.prepareStatement(query);

            // 2) 위치홀더(?)에 알맞은 값 세팅
            pstmt.setString(1, member.getMemberId());
            pstmt.setString(2, member.getMemberPwd());

            // 3) SQL 수행 후 결과를 반환받아 저장
            rset = pstmt.executeQuery();

            // 4) 조회 결과가 있을 경우 Member 객체에 조회 내용을 저장
            if(rset.next()) {
                loginMember = new Member(rset.getInt("MEMBER_NO"),
							 rset.getString("MEMBER_ID"), 
							 rset.getString("MEMBER_NM"), 
							 rset.getString("MEMBER_PHONE"),
							 rset.getString("MEMBER_EMAIL"), 
							 rset.getString("MEMBER_ADDR"), 
							 rset.getString("MEMBER_INTEREST"), 
							 rset.getString("MEMBER_GRADE"));
            }
        } finally {
            close(rset);
            close(pstmt);
        }

        return loginMember;
    }
}



header.jsp

<!-- 모달 body 부분에 href 경로 지정-->
 <form class="form-signin" method="POST" action="${ contextPath }/member/login.do">



LoginServlet.java

@WebServlet("/member/login.do")
public class LoginServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        
        // 1. POST 방식으로 전달된 데이터의 문자 인코딩 변경
        request.setCharacterEncoding("UTF-8");

        // 2. 파라미터를 얻어와 변수에 저장
        String memberId = request.getParameter("memberId");
        String memberPwd = request.getParameter("memberPwd");
        String save = request.getParameter("save"); // 체크 시 on, 아니면 null

        // System.out.println(memberId + " / " + memberPwd + " / " + save);
        // 정보를 잘 가져오는지 확인

        // JDBC 수행
        // 아이디와 비밀번호를 하나의 vo에 담아서 service로 전달
        // 3. 아이디와 비밀번호를 Member 객체에 세팅
        Member member = new Member();
        member.setMemberId(memberId);
        member.setMemberPwd(memberPwd);

        try {
            // 4. Member 객체를 service로 전달하여 결과 반환 받기
            Member loginMember = new MemberService().loginMember(member);

            // System.out.println(loginMember); 정보를 잘 가져왔는지 확인

            // 로그인 정보는 로그아웃 또는 브라우저가 종료될 때까지 유지되어야 함
            //   --> session 활용

            // 5. 응답 화면 문서 타입 지정
            response.setContentType("text/html; charset=UTF-8");

            // 6. Session 객체를 얻어와 로그인 정보 추가
            HttpSession session = request.getSession();

            // 6-1. 로그인이 성공했을 때만 Session에 로그인 정보 추가하기
            if(loginMember != null) {
                // 6-2. 30분 동안 동작이 없을 경우 Session 만료
                session.setMaxInactiveInterval(60 * 1); // 테스트용 1분 후 만료

                // 6-3. Session에 로그인 정보 추가
                session.setAttribute("loginMember", loginMember);
                
            } else{
                // 로그인이 실패했을 경우 경고창 띄우기
                // -> session에 문자열을 담아 리다이렉트
                
                // sweet alert 사용하기
                session.setAttribute("swalIcon", "error");
                session.setAttribute("swalTitle", "로그인 실패");
                session.setAttribute("swalText", "아이디 또는 비밀번호를 확인해주세요.");
            }

            
            // redirect 방식을 이용하여 로그인을 요청했던 페이지로 이동한다.
            /* 
                forward 같은 경우에는 이동하는 페이지로 request, response
                객체를 그대로 위임하고, 주소를 위임 전 주소로 유지하지만

                redirect는 이전 request, response를 폐기하고 새롭게 만들어서
                지정된 주소로 새로운 요청을 보낸다.
                    -> 새롭게 요청을 보내기 때문에 이전 요청 주소가 아닌 새로운 요청 주소가 타나남
            */
            //  request.getHeader("referer") : 요청 전 페이지 주소가 담겨있다.
            response.sendRedirect(request.getHeader("referer"));
        } catch {
            e.printStackTrace();
        }
    }
       protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        doGet(request, response);
   }
}



header.jsp

  • header.jsp 내 body 상단 부분에 작성
<!-- 로그인 실패 등 서버로부터 전달받은 메세지를 경고창으로 출력 -->

<!-- 서버로부터 전달받은 메세지가 있는지 검사하기 -->
<c:if test="${!empty sessionScope.swalTitle}">
    <script>
        swal({icon : "${swalIcon}", title : "${swalTitle}", text : "${swalText}"});
    </script>

    <!-- 2) 한 번 출력한 메세지를 Session에서 삭제 -->
    <c:remove var="swalIcon" />
    <c:remove var="swalTitle" />
    <c:remove var="swalText" />
</c:if>



  • header.jsp 내 로그인 모달창 전에 작성
<c:choose>
    <!-- 로그인이 되어있지 않을 때 == session에 loginMember 값이 없을 때 -->
    <c:when test="${empty sessionScope.loginMember}">
            <!-- 헤더에 있는 login 버튼 클릭 시 #modal-container-1 이라는 
            아이디를 가진 요소를 보여지게 함. -->
            <li class="nav-item active">
                <a class="nav-link" data-toggle="modal" href="#modal-container-1">
                    Login
                </a>
            </li>
    </c:when>

    <!-- 로그인이 되어있을 때 -->
    <c:otherwise>
        <li class="nav-item active">
            <!-- 로그인 회원의 이름을 가져와 출력 -->
            <a class="nav-link" href="#">${loginMember.memberName}</a>
        </li>
        <li class="nav-item active">
            <a class="nav-link" href="${contextPath}/member/logout.do">Logout</a>
        </li>
        </c:otherwise>
    </c:otherwise>
</c:choose>



오류 페이지

20201224_13

LoginServlet.java

  • LoginServlet.java 내 catch 구문에 작성
request.setAttribute("errorMsg", "로그인 과정에서 오류가 발생했습니다.");

// 요청 위임 객체 생성
RequestDispatcher view 
    = requset.getRequestDispatcher("/WEB-INF/views/common/errorPage.jsp");

view.forward(request, response);



errorPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>에러페이지</title>
</head>
<body>
    <h1 align="center">${errorMsg}</h1>

    <div align="center">
        <button onclick="history.back();">이전 페이지로 이동</button>
        <button onclick="location.href='${contextPath}'">메인 화면으로 돌아가기</button>
    </div>
</body>
</html>



로그아웃

20201224_14



LogoutServlet.java

@WebServlet("/member/logout.do")
public class LogoutServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 로그인 상태 -> DB에서 조회한 회원 정보가 Session에 존재하는 것
		// 로그아웃 상태 -> Session에 회원 정보가 없는 것
		
		// 세션 만료(세션 무효화)
		request.getSession().invalidate();
		
		
		// 로그아웃 후 메인 or 로그아웃을 수행한 페이지
//		response.sendRedirect(request.getContextPath()); // 메인
		response.sendRedirect(request.getHeader("referer")); // 로그아웃을 수행한 페이지
	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

댓글남기기