클라우드 융합 Full-stack 웹 개발자 양성과정/Servlet, JSP

Servlet/JSP - 로그아웃기능, 회원가입페이지, 마이페이지(정보변경)

thesunset 2022. 11. 10. 17:42

1. 로그아웃기능

 

우리가 menubar에서 보여주었던 로그인 성공 시 보게 될 화면에 로그아웃 a태그에 경로를 입력해줄 예정

<a href="/jsp/logout.me">로그아웃</a>

절대경로 방식의 경우 context Root가 가장 먼저 > 내가 정한 서블릿매핑값

* 이때 contextRoot의 경우 언제든 변할 수 있기에 

 

바뀔수도 있는 ContextRoot경로를 ***contextPath

String contextPath = request.getContextPath();

/jsp와 동일한 값으로 변수로 지정해놓고 아래와 같이 바꾸기 

<!-- <form action="/jsp/login.me" method="post"> -->
<form action="<%= contextPath %>/login.me" method="post">

<!-- <a href="/jsp/logout.me">로그아웃</a> -->
<a href="<%= contextPath %>/logout.me">로그아웃</a>

<div class="menu"><a href="<%= contextPath %>">HOME</a></div>

 

<com.kh.member.controller>에 LogoutController.jsp 생성 후 매핑값을 /logout.me로 지정

 

로그아웃 요청에 대한 처리 => session을 만료시킨다 (=무효화한다)

무효화 메소드 == invalidate() => session에서 제공하는 메소드 

 

- session객체 생성과 무효화

HttpSession session = request.getSession();
session.invalidate();

 

- 요청을 받앋으니? 응답 받아주기 ! 응답페이지 =>  sendRedirect방식

: index.jsp가보여지게끔 => localhost:8001/jsp/

response.sendRedirect(request.getContextPath());

 

2. 회원가입기능

 

회원가입 폼 파일 만들기 

<WebContent/views/member>memberEnrollForm

 

- 항상존재하는 메뉴바 가져오기 

나보다 위에있는 view폴더(상위폴더 : ../) > common폴더 > menubar.jsp

<%@ include file="../common/menubar.jsp" %>

- 회원가입 페이지 구성하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입페이지</title>
<style>
	.outer{
		width: 1000px;
		margin: auto;
		background-color: olive;
		margin-top: 5px;
		color: beige;
	}
	#enroll-form input{
		margin: 5px;
	}
</style>

</head>
<body>
	<%@ include file="../common/menubar.jsp" %>
	<div class="outer">
		<br>
		<h2 align="center">회원가입</h2>
		
		<form action="<%=contextPath%>/insert.me" method="post" id="enroll-form">
		<!-- 요청할 어플리케이션 매핑값 action -->
		<!--아이디, 비밀번호, 이름, 전화번호, 이메일주소, 주소, 취미-->

			<table align="center">
				<tr>
					<td>* 아이디 : </td><!--notnull이면 *-->
					<td><input type="text" name="userId" maxlength="12" required></td>
					<td><button>중복확인</button></td>
					<!-- 중복확인은 나중에 AJAX배우고 다음주에 할 예정 -->
				</tr>
				<tr>
					<td>* 비밀번호</td>
					<td><input type="password" name="userPwd" maxlength="15" required></td>
					<td></td>
				</tr>
				<tr>
					<td>* 비밀번호 확인</td>
					<td><input type="password" maxlength="15" required></td>
					<td></td>
					<!-- 자바스크립트에서 안맞으면 요청이 안되도록 지정할 예정 -->
				</tr>
				<tr>
					<td>* 이름</td>
					<td><input type="text" name="userName" maxlength="5" required></td>
					<td></td>
				</tr>
				<tr>
					<td>&nbsp;&nbsp;전화번호</td>
					<td><input type="text" name="phone" placeholder="-를 포함해서 입력해주세요."></td>
					<td></td>
				</tr>
				<tr>
					<td>&nbsp;&nbsp;이메일</td>
					<td><input type="email" name="email"></td>
					<td></td>
				</tr>
				<tr>
					<td>&nbsp;&nbsp;주소</td>
					<td><input type="text" name="address"></td>
					<td></td>
				</tr>
				<tr>
					<td>&nbsp;&nbsp;취미</td>
					<td colspan="2">
						<input type="checkbox" id="climbing" value="등산" name="interest"><label for="climbing">등산</label>
						<input type="checkbox" id="drinking" value="음주" name="interest"><label for="drinking">음주</label>
						<input type="checkbox" id="challenge" value="챌린지" name="interest"><label for="challenge">챌린지</label>
						<br>
						<input type="checkbox" id="community" value="커뮤니티" name="interest"><label for="community">커뮤니티</label>
						<input type="checkbox" id="vegetarian" value="채식" name="interest"><label for="vegetarian">채식</label>
						<input type="checkbox" id="rest" value="휴식" name="interest"><label for="rest">휴식</label>
					</td>
				</tr>
			</table>

			<br><br>

			<div align="center">
				<button type="submit">회원가입</button>
				<button type="reset">초기화</button>
			</div>
			<br><br>
		</form>
	</div>
</body>
</html>

- "회원가입 버튼"을 누르면 회원가입 페이지로 이동

<menubar.jsp>

<button type="button" onclick="enrollPage();">회원가입</button>

버튼에 onclick속성 추가 :  BOM- location객체-href속성

<script>
function enrollPage(){
        //페이지 이동
        //자바스크립트 location.href
    location.href = "<%= contextPath %>/views/member/memberEnrollForm.jsp"
}

</script>

http://localhost:8001/jsp/views/member/memberEnrollForm.jsp

=> 웹어플리케이션의 디렉토리 구조가 url에 노출됨 => 보안에 취약

=> 안보이게 해주어야 함 

 

서블릿이 처리할 수 있도록 함

서블릿 만들기 => 앞으로 서블릿으로 할 예정 

<com.kh.member.controller>MemberEnrollFromController.java

=> 회원가입 폼 띄워주기

더보기

서블릿에 화면 띄워주는 방법 두 가지

1) RequestDispatcher 객체를 이용하는 방법(forwarding)
2) sendRedirect 방법(url재요청방식) = url이없어서 불가능

1)방법 이용

request.getRequestDispatcher("views/member/memberEnrollForm.jsp").forward(request, response);

form의 action속성값 "<%=contextPath%>/insert.me"로 이동

 

- controller

<com.kh.member.controller>MemberInsertController 회원가입 

받은 데이터를 회원가입처리해주기 (insert)

 

1) POST 방식이기에 인코딩해주기

request.setCharacterEncoding("UTF-8");

2) request객체로부터 요청 시 전달값 뽑기

String userId = request.getParameter("userId"); 	// 필수입력 
String userPwd = request.getParameter("userPwd");	// 필수입력
String userName = request.getParameter("userName"); // 필수입력
String phone = request.getParameter("phone");		// 빈 문자열이 들어갈 수 있음 
String email = request.getParameter("email");		
String address = request.getParameter("address");
String[] interestArr = request.getParameterValues("interest"); //["음주", "등산"] / null

//음주, 등산, 챌린지 (이런형식으로 배열을 출력할 것)
//String.join("구분자", 배열명)
String interest = "";

if(interestArr != null) {
    interest = String.join(",", interestArr);
}

3) Member객체에 담기 

Member m = new Member();
m.setUserId(userId);
m.setUserPwd(userPwd);
m.setUserName(userName);
m.setPhone(phone);
m.setEmail(email);
m.setAddress(address);
m.setInterest(interest);

4) 요청처리 (Service단으로 부터 전달받음)

int result = new MemberService().insertMember(m);

5) 처리결과를 가지고 응답화면 지정

성공 시 -> /jsp 를 요청 => url 재요청방식(sendRedirect방식)

if(result > 0) { 

    response.sendRedirect(request.getContextPath());			
    request.getSession().setAttribute("alertMsg", "회원가입에 성공했습니다.");
    //session이기 때문에 생성 후 set해야함

}

실패 시 -> 에러페이지

request.setAttribute("errorMsg","회원가입에 실패했습니다.");

RequestDispatcher view = request.getRequestDispatcher("views/common/errorPage.jsp");
view.forward(request, response);
더보기

에러페이지 errorPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String errorMsg = (String)request.getAttribute("errorMsg");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1 align="center" style="color:red; margin-top:100px;"><%=errorMsg %></h1>
</body>
</html>

- Service

public int insertMember(Member m) {

    Connection conn = JDBCTemplate.getConnection();
    int result = new MemberDao().insertMember(conn, m);
    //성공했다면 1, 실패했으면 0

	if(result > 0) {
        JDBCTemplate.commit(conn);
    } else {
        JDBCTemplate.rollback(conn);
    }
    JDBCTemplate.close(conn);
    return result;
}

- Dao

public int insertMember(Connection conn, Member m) {

    //INSERT => 처리된 행의 개수
    int result = 0;
    PreparedStatement pstmt = null;
    String sql = prop.getProperty("insertMember");

    try {
        pstmt = conn.prepareStatement(sql);

        //위치홀더
        pstmt.setString(1, m.getUserId());
        pstmt.setString(2, m.getUserPwd());
        pstmt.setString(3, m.getUserName());
        pstmt.setString(4, m.getPhone());
        pstmt.setString(5, m.getEmail());
        pstmt.setString(6, m.getAddress());
        pstmt.setString(7, m.getInterest());

        //SQL실행 및 결과 받기
        //insert/update/delete => pstmt.executeUpdate();
        result = pstmt.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCTemplate.close(pstmt);
    }
    return result;
}

성공 시 alert창이 뜬 뒤 contextRoot페이지로 이동

 

3. 마이페이지기능

로그인 시, 화면에는 마이페이지, 로그아웃 버튼으로 바뀜 

이때, 마이페이지에 가서 정보수정이나 탈퇴를 진행시켜줄 예정임

<a href="<%= contextPath%>/myPage.me)">마이페이지</a>

** 추가로 해줘야할 작업 (로그아웃 후 url을 직접 요청 했더니 마이페이지가 뜸 => 방지해야함)

<com.kh.member.controller> MyPageController

접속자의 정보 => session - 로그인 전 : loginUser 키값에 해당하는 벨류가 null값
- 로그인 후 : loginUser 키값에 해당하는 value가 Member => 포워딩

HttpSession session = request.getSession();

- 로그인 여부(유/무)

    if(session.getAttribute("loginUser")==null) {
        session.setAttribute("alertMsg", "로그인 후 진행해주세요.");
        response.sendRedirect(request.getContextPath());

        //*주의 세션은 브라우저당 하나 !!만 적용

    }else {

    request.getRequestDispatcher("views/member/myPage.jsp").forward(request, response);
    }

 

 

 

매핑값으로 /update.me를 지정한 서블릿 생성

<com.kh.member.controller>MemberUpdateController

1) POST방식 => 인코딩

request.setCharacterEncoding("UTF-8");

2) request로부터 요청 시 전달한 값을 뽑기 

String userId = request.getParameter("userId");
String userName = request.getParameter("userName");
String phone = request.getParameter("phone");
String email = request.getParameter("email");
String address = request.getParameter("address");
String[] interestArr = request.getParameterValues("interest"); //null
//반드시 식별자를 가져와야함! (쿼리문에 조건을 걸기 위해) ==userId

String interest ="";
if(interestArr != null) {
    interest = String.join(",", interestArr);
}

3) VO객체에 담기 

Member m = new Member();
m.setUserId(userId);
m.setUserName(userName);
m.setPhone(phone);
m.setEmail(email);
m.setAddress(address);
m.setInterest(interest);

4)Service단으로 전달 

new MemberService().updateMember(m);

- Service

public Member updateMember(Member m) {

    Connection conn = JDBCTemplate.getConnection();

    int result = new MemberDao().updateMember(conn, m);

    Member updateMem = null; //실패했을 때를 위해서 바깥에 선언

    if(result > 0) {
        JDBCTemplate.commit(conn);
        //갱신된 회원 객체를 다시 조회해오기
        updateMem = new MemberDao().selectMember(conn, m.getUserId());

    } else {
        JDBCTemplate.rollback(conn);
    }

    JDBCTemplate.close(conn);
    return updateMem;
}

* 정보수정 성공 시 정보수정페이지에 담긴 값도 담겨야 함 => 즉, 새롭게 바뀐 값으로 다시 조회해와야 함

=> return값도 int형이 아닌 Member객체(updateMem)로

 

- Dao (update)

public int updateMember(Connection conn, Member m) {

    int result = 0; 
    PreparedStatement pstmt = null;
    String sql = prop.getProperty("updateMember");

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, m.getUserName());
        pstmt.setString(2, m.getPhone());
        pstmt.setString(3, m.getEmail());
        pstmt.setString(4, m.getAddress());
        pstmt.setString(5, m.getInterest());
        pstmt.setString(6, m.getUserId());

        result = pstmt.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCTemplate.close(pstmt);
    }
    return result;
}

- Dao(select)

public Member selectMember(Connection conn, String userId) {

    //SELECT문 => MEMBER 
    Member m = null;
    PreparedStatement pstmt = null;
    ResultSet rset = null;

    String sql = prop.getProperty("selectMember");

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, userId);

        rset = pstmt.executeQuery();

        if(rset.next()) {
            m = new Member(rset.getInt("USER_NO"),
                           rset.getString("USER_ID"),
                           rset.getString("USER_PWD"),
                           rset.getString("USER_NAME"),
                           rset.getString("PHONE"),
                           rset.getString("EMAIL"),
                           rset.getString("ADDRESS"),
                           rset.getString("INTEREST"),
                           rset.getDate("ENROLL_DATE"),
                           rset.getDate("MODIFY_DATE"),
                           rset.getString("STATUS"));


        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCTemplate.close(rset);
        JDBCTemplate.close(pstmt);
    }

    return m;
}