이번엔 회원상세조회 페이지를 구현할 것이다!
상세 조회를 통해서 정보를 수정하고, 회원탈퇴페이지로 이동해서 회원탈퇴도 가능하게 만들었다.
[memberView.do]

아이디는 고유값이라 수정할 수 없으니 span태그로 감싸고 비밀번호는 변경할 비밀번호를 입력하고 변경되게 했다.
현재 비밀번호와 변경할 비밀번호를 입력하게 할 수도 있었겠지만...프로젝트 마감일 까지 그리 넉넉하지 않았기 때문에 생략했다...ㅎ
정보 수정을 누르면 입력한 정보들로 수정되고, 회원탈퇴를 누르면 탈퇴 페이지로 이동한다.
[memberView.jsp]
<%@page import="org.project.dto.MemberDto"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
MemberDto member =
(MemberDto)request.getAttribute("member");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MemberView</title>
<link rel="stylesheet" href="css/memberView.css" />
<script src="js/updateOk.js" defer></script>
</head>
<body>
<%@include file="common/header.jsp" %>
<div class="container">
<div class="inner-con">
<div class="update">
<form action="updateOk.do" method="post" id="updateForm">
<table>
<thead>
<tr>
<th>MODIFY</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label for="userId">아이디</label> <br />
<input type="hidden" name="userId" id="userId" value="<%=member.getUserId() %>"/>
<span class="id"><%=member.getUserId() %></span>
</td>
</tr>
<tr>
<td>
<label for="userPw">비밀번호</label> <br />
<input type="password" name="userPw" id="userPw" placeholder="비밀번호를 입력해 주세요." />
</td>
</tr>
<tr>
<td>
<label for="userPw2">비밀번호 재확인</label> <br />
<input type="password" name="userPw2" id="userPw2" placeholder="비밀번호를 다시 입력해 주세요." />
</td>
</tr>
<tr>
<td>
<span id="pwch" class="pwch2"></span>
</td>
</tr>
<tr>
<td>
<label for="userName">이름</label> <br />
<input type="text" name="userName" id="userName" value="<%=member.getUserName() %>" />
</td>
</tr>
<tr>
<td>
<label for="userBirthday">생년월일</label> <br />
<input type="text" name="userBirthday" id="userBirthday" value="<%=member.getUserBirthday() %>" />
</td>
</tr>
<tr>
<td>
<label for="userPhone">휴대전화</label> <br />
<input type="text" name="userPhone" id="userPhone" value="<%=member.getUserPhone() %>" />
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<input type="button" value="정보수정" id="updateOkBtn" />
<hr />
<a href="memberDeleteView.do?userId=<%=member.getUserId() %>">회원탈퇴</a>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
<%@include file="common/footer.jsp" %>
</body>
</html>
/*memberView.css*/
@import url("common/reset.css");
@import url("common/header.css");
@import url("common/footer.css");
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Sunflower:wght@500&display=swap');
.container {
width: 100%;
height: calc(100vh - 180px);
}
.inner-con {
width: 100%;
height: calc(100vh - 180px);
background-image: url("../img/ekuse7.jpg");
background-repeat: no-repeat;
background-size: cover;
background-position: bottom;
display: flex;
justify-content: center;
}
.update {
background: rgba(255, 255, 255, 0.5);
width: 700px;
display: flex;
align-items: center;
justify-content: center;
}
.update > form > table {
margin-left: auto;
margin-right: auto;
padding: 10px 10px;
width: 500px;
font-family: 'Sunflower', sans-serif;
letter-spacing: 2px;
}
.update > form > table thead tr th {
color: white;
text-shadow: 1px 1px 1px gray;
font-size: 1.5em;
line-height: 50px;
font-family: 'Nunito', sans-serif;
}
.update > form > table tbody label {
line-height: 40px;
font-size: 1.2em;
color: #5d4037;
}
.id {
color: #004c8c;
}
.update > form > table tbody input {
width: 100%;
height: 40px;
border: 1px solid #ddd;
border-radius: 5px;
padding: 2px 5px;
margin: 2px 0px;
font-family: 'Sunflower', sans-serif;
}
#pwch {
color: red;
}
.pwch2 {
color: blue !important;
}
.update > form > table tfoot input {
width: 100%;
height: 40px;
border: none;
background-color: #A57C55;
color: #FFFFFF;
font-family: 'Sunflower', sans-serif;
letter-spacing: 5px;
font-size: 1em;
margin-top: 5px;
}
.update > form > table tfoot hr {
margin: 10px 0px;
}
.update > form > table tfoot a {
color: #8c0032;
float: right;
font-family: 'Sunflower', sans-serif;
letter-spacing: 2px;
}
여기서 가장가장가장!!중요한 것은
<%
MemberDto member = (MemberDto)request.getAttribute("member");
%>
이 부분인데 member에 값이 제대로 전달되지 않았다면 여기서 에러가 떠서 500에러를 만나게 될 것이다...
jsp까지 왔는데 에러가 뜬다면 그건 높은 확률로 Dao에서 오류가 있는거일테니 침착하게 꼼꼼하게 Dao를 다시 보자.
만약 member변수가 null이었다면 애초에 memberView.jsp로 연결되지 않고 인덱스로 이동되었을 것이다.
jsp로 넘어왔는데 에러가 떴다? 그럼 member에 뭐가 담겨서 오긴 했는데 정상적이지 않아서 그럴 것이다..
오류가 어디서 나는지를 찾아내는게 중요하다!! 처음엔 오류 뜨면 어디서 뭐가 틀렸는지 모르겠어서 멘붕이었지만 이제 가닥이 조금 잡혀간달까...
이건 나중에 Commend 부분에서 한번 더 언급하겠다!
아이디는 수정할 수 없기 때문에 span태그로 감싸서 수정하지 못하고 표시만 되게 하고, DB에 값이 전송은 되야 하기 때문에 input type="hidden" value="<%=member.getUserId %>" 를 통해서 값이 DB로 전송되게 했다.
그 외엔 회원가입과 동일하다.
[updateOk.js]
/*updateOk.js*/
const updateForm=document.querySelector('#updateForm');
const userId=document.querySelector('#userId');
const userPw=document.querySelector('#userPw');
const userPw2=document.querySelector('#userPw2');
const userName=document.querySelector('#userName');
const userBirthday=document.querySelector('#userBirthday');
const userPhone=document.querySelector('#userPhone');
const updateOkBtn=document.querySelector('#updateOkBtn');
//비밀번호 체크
userPw2.addEventListener('keyup',()=>{
if(userPw.value!=userPw2.value) {
pwch.innerText="비밀번호가 틀립니다.";
pwch.classList.remove('pwch2');
} else {
pwch.innerText="비밀번호가 일치합니다.";
pwch.classList.add('pwch2');
}
});
//유효성 검사
updateOkBtn.addEventListener('click', ()=>{
if(userPw==null || userPw.value=="" || userPw.value<=0) {
alert("비밀번호를 입력하세요!");
userPw.focus();
return false;
}
if(userPw2==null || userPw2.value=="" || userPw2.value<=0) {
alert("비밀번호를 입력하세요!");
userPw2.focus();
return false;
}
if(userPw.value!=userPw2.value) {
alert("비밀번호가 일치하지 않습니다.");
userPw2.focus();
return false;
}
if(userName==null || userName.value=="" || userName.value<=0) {
alert("이름을 입력하세요!");
userName.focus();
return false;
}
if(userBirthday==null || userBirthday.value=="" || userBirthday.value<=0) {
alert("생년월일을 입력하세요!");
userBirthday.focus();
return false;
}
if(userPhone==null || userPhone.value=="" || userPhone.value<=0) {
alert("전화번호를 입력하세요!");
userPhone.focus();
return false;
}
alert("회원 정보 수정을 완료했습니다!");
updateForm.submit();
});
회원가입 자바스크립트를 복사해서 수정만 했다.
[ProjectDao - memberViewDo, updateDo]
package org.project.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import org.project.dbConnect.DBConnect;
import org.project.dto.MemberDto;
//DataBase Access Object
public class ProjectDao {
//싱글톤
//클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 객체를 만들어 사용하는 디자인 패턴
//생성자를 외부에서 호출할 수 없도록 private 접근제한자
private static class singleton {
//정적 필드 static final => 한 번 초기값이 저장되면 변경 불가
private static final ProjectDao INSTANCE=new ProjectDao();
}
//생성자
private ProjectDao() {}
//외부 호출이 가능(public) 정적(static) 메소드
public static ProjectDao getInstance() {
return singleton.INSTANCE;
}
//회원상세조회
public MemberDto memberViewDo(String userId) {
MemberDto member=null;
Connection conn=null;
PreparedStatement pstm=null;
ResultSet rs=null;
String query="";
try {
conn=DBConnect.getConnection();
query="select * from pj_member where userId=?";
pstm=conn.prepareStatement(query);
pstm.setString(1, userId);
rs=pstm.executeQuery();
if(rs.next()) {
member=new MemberDto(rs.getString(1), rs.getString(2),
rs.getString(3), rs.getString(4), rs.getString(5));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(conn!=null) conn.close();
if(pstm!=null) pstm.close();
} catch (Exception e) {
e.printStackTrace();
} finally {}
}
return member;
}
//회원정보수정
public int updateDo(String userId, String userPw, String userName,
String userBirthday, String userPhone) {
int rs=0;
Connection conn=null;
PreparedStatement pstm=null;
String query="";
try {
conn=DBConnect.getConnection();
query="update pj_member set userPw=?, userName=?, "
+ "userBirthday=?, userPhone=? where userId=?";
pstm=conn.prepareStatement(query);
pstm.setString(1, userPw);
pstm.setString(2, userName);
pstm.setString(3, userBirthday);
pstm.setString(4, userPhone);
pstm.setString(5, userId);
rs=pstm.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(conn!=null) conn.close();
if(pstm!=null) pstm.close();
} catch (Exception e) {
e.printStackTrace();
} finally {}
}
return rs;
}
}
회원상세조회는 MemberDto를 참조하는 member 변수를 생성하고 쿼리문을 실행해서 값을 하나하나 담는다.
회원정보를 수정하는 updateDo는 쿼리문에 문제가 없다면 1로 리턴될거고 아니면 0이 리턴된다.
[MemberViewCommend]
package org.project.commend;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.project.dao.ProjectDao;
import org.project.dto.MemberDto;
public class MemberViewCommend implements ExcuteCommend{
@Override
public void excuteQueryCommend(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("회원상세보기 commend");
String userId=request.getParameter("userId");
ProjectDao dao=ProjectDao.getInstance();
MemberDto member=dao.memberViewDo(userId);
String url="";
if(member!=null) {
System.out.println("회원상세조회 Ok");
request.setAttribute("member", member);
url="/memberView.jsp";
} else {
System.out.println("회원상세조회 Fail");
url="/index.do";
}
request.setAttribute("url", url);
}
}
Commend에서 member 변수에 값이 담겨서 넘어 왔다면 memberView.jsp로 이동 시킬것이고 null이라면 인덱스로 보낼 것이다.
오류가 뜬다면 다시한번 Dao를 꼼꼼하게 살펴보자.
[UpdateOkCommend]
package org.project.commend;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Session;
import org.project.dao.ProjectDao;
public class UpdateOkCommend implements ExcuteCommend{
@Override
public void excuteQueryCommend(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("회원수정 commend");
String userId=request.getParameter("userId");
String userPw=request.getParameter("userPw");
String userName=request.getParameter("userName");
String userBirthday=request.getParameter("userBirthday");
String userPhone=request.getParameter("userPhone");
ProjectDao dao=ProjectDao.getInstance();
int rs=dao.updateDo(userId, userPw, userName, userBirthday, userPhone);
String url="";
if(rs!=1) {
System.out.println("회원정보수정 Fail");
url="/index.do";
} else {
System.out.println("회원정보수정 Ok");
url="/index.do";
}
request.setAttribute("url", url);
}
}
[Controller]
package org.project.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.project.commend.DeleteOkCommend;
import org.project.commend.ExcuteCommend;
import org.project.commend.JoinOkCommend;
import org.project.commend.LoginOkCommend;
import org.project.commend.LogoutCommend;
import org.project.commend.MemberViewCommend;
import org.project.commend.UpdateOkCommend;
@WebServlet("*.do")
public class Controller extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); //한글 인코딩(한글처리)
String path=request.getContextPath(); //프로젝트 path만 얻어온다.
// => /webProject_KM
String uri=request.getRequestURI(); //프로젝트와 파일경로까지 얻어온다.
// => /webProject_KM/index.do
String basicURL=uri.substring(path.length());
// => /index.do
System.out.println(basicURL);
ExcuteCommend commend=null;
String url="";
if(basicURL.equals("/index.do")) {
url="/index.jsp";
} else if(basicURL.equals("/loginView.do")) {
url="/loginView.jsp";
} else if(basicURL.equals("/joinView.do")) {
url="/joinView.jsp";
} else if(basicURL.equals("/joinOk.do")) {
commend=new JoinOkCommend();
commend.excuteQueryCommend(request, response);
url=(String)request.getAttribute("url");
} else if(basicURL.equals("/loginOk.do")) {
commend=new LoginOkCommend();
commend.excuteQueryCommend(request, response);
url=(String)request.getAttribute("url");
} else if(basicURL.equals("/logout.do")) {
commend=new LogoutCommend();
commend.excuteQueryCommend(request, response);
url=(String)request.getAttribute("url");
} else if(basicURL.equals("/admin.do")) {
url="/admin.jsp";
} else if(basicURL.equals("/memberListView.do")) {
url="/memberListView.jsp";
} else if(basicURL.equals("/memberView.do")) {
commend=new MemberViewCommend();
commend.excuteQueryCommend(request, response);
url=(String)request.getAttribute("url");
} else if(basicURL.equals("/updateOk.do")) {
commend=new UpdateOkCommend();
commend.excuteQueryCommend(request, response);
url=(String)request.getAttribute("url");
}
RequestDispatcher disp=request.getRequestDispatcher(url);
disp.forward(request, response); //해당 ViewPage로 포워딩
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
doGet(request, response);
}
}
컨트롤러에서는 이렇게 요청을 받아서 처리한다.
이제 회원탈퇴페이지만 남았다!
'[개발 언어 & 프레임워크] > JSP' 카테고리의 다른 글
[JSP/Servlet] HttpServletRequest, HttpServletResponse 객체 이해하기 (0) | 2022.11.28 |
---|---|
[JSP] 5. WebProject(홈페이지 만들기) - 회원 탈퇴 구현하기 (0) | 2022.08.15 |
[JSP] 3. WebProject(홈페이지 만들기) - 회원목록 조회하기 (0) | 2022.08.15 |
[JSP] 2. WebProject(홈페이지 만들기) - 로그인 구현하기 (0) | 2022.08.11 |
[JSP] 1. WebProject(홈페이지 만들기) - 회원가입 구현하기 (0) | 2022.08.09 |