myPage
- jsp 파일로 작성한다.
- 로그인 성공 후엔 마이페이지와 로그아웃이 보이므로 myPage에 menubar를 include해야 한다.
- 이때 menubar를 include하면 변수 contextPath를 사용할 수 있다.
- 마이페이지에서 아이디는 변경할 수 없으므로(고유값) readonly를 사용하여 읽기만 할 수 있게 한다.
<%@ include file="../common/menubar.jsp" %>
<%
String userId = loginUser.getUserId();
String userPwd = loginUser.getUserPwd();
String userName = loginUser.getUserName();
// 해당 값이 없으면 빈 문자열, 있으면 해당 값으로 변수를 초기화 선언
String phone = (loginUser.getPhone() == null) ? "" : loginUser.getPhone();
String email = (loginUser.getEmail() == null) ? "" : loginUser.getEmail();
String address = (loginUser.getAddress() == null) ? "" : loginUser.getAddress();
String interest = (loginUser.getInterest() == null) ? "" : loginUser.getInterest();
%>
<div class="outer">
<h2 align="center">마이페이지</h2>
<form id="mypage-form" action="<%=contextPath %>/update.me" method="post">
<table>
<tr>
<td>*아이디</td>
<td><input type="text" name="userId" maxlength="12" value="<%=userId %>" required readonly></td>
</tr>
<tr>
<td>*이름</td>
<td><input type="text" name="userName" value="<%=userName %>" maxlength="6" required></td>
<td></td>
</tr>
<tr>
<td>전화번호</td>
<td><input type="text" name="phone" value="<%=phone %>" placeholder="(-) 포함하여 입력하세요."></td>
<td></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="email" name="email" value="<%=email %>"></td>
<td></td>
</tr>
<tr>
<td>주소</td>
<td><input type="text" name="address" value="<%=address %>"></td>
<td></td>
</tr>
<tr>
<td>관심분야</td>
<td>
<input type="checkbox" name="interest" id="" value="미술">
<label for="art">미술</label>
<input type="checkbox" name="interest" id="" value="운동">
<label for="sports">운동</label>
<input type="checkbox" name="interest" id="" value="영화">
<label for="movie">영화</label>
<input type="checkbox" name="interest" id="" value="음악">
<label for="music">음악</label>
<input type="checkbox" name="interest" id="" value="게임">
<label for="game">게임</label>
<input type="checkbox" name="interest" id="" value="요리">
<label for="cooking">요리</label>
</td>
<td></td>
</tr>
</table>
<script>
$(function(){
var interest = "<%=interest%>";
// 문자열.search(비교값): 문자열에서 문자값과 일치하는 값의 시작인덱스값을 반환
// 0부터 시작, 없으면 -1 반환
$("input[type=checkbox]").each(function(){
// 순차적으로 접근한 input:chk 요소에 value값이 interest 안에 포함됐는지 확인
if(interest.search($(this).val()) != -1){
// interest 문자열 안에 체크박스 value가 포함되어 있지않으면 -1 반환
$(this).attr("checked", true);
}
});
})
</script>
<div align="center">
<button type="submit" class="btn btn-info">정보 변경</button>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#updatePwdForm">비밀번호 변경</button>
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteMemberForm">회원 탈퇴</button>
</div>
</form>
</div>
<!-- 비밀번호 변경 클릭 시 -->
<!-- The Modal -->
<div class="modal" id="updatePwdForm">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">비밀번호 변경</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<form action="<%=contextPath%>/updatePwd.me" method="post">
<!-- 현재 비밀번호, 변경할 비밀번호, 비밀번호 확인 -->
<!-- 회원정보 식별할 회원 아이디도 데이터를 보내야한다.
이때 hidden으로 처리(보여줄 필요가 없기 때문.) -->
<input type="hidden" name="userId" value="<%=userId%>">
<table>
<tr>
<td>현재 비밀번호</td>
<td><input type="password" name="userPwd" required></td>
</tr>
<tr>
<td>변경할 비밀번호</td>
<td><input type="password" name="updatePwd" id="pwd1" required></td>
</tr>
<tr>
<td>변경할 비밀번호 확인</td>
<td><input type="password" name="checkPwd" id="pwd2" required></td>
</tr>
</table>
<br>
<button type="submit" class="btn btn-warning" onclick="return validatePwd();">비밀번호 변경</button>
</form>
<script>
function validatePwd(){
if($("input[name=updatePwd]").val() != $("input[name=checkPwd]").val()){
// #pwd1과 #pwd2가 일치하지 않을 때 false로 반환한다.
alert("비밀번호가 일치하지 않습니다.");
return false;
}
}
</script>
</div>
</div>
</div>
</div>
<!-- 회원 탈퇴 클릭 시 -->
<!-- The Modal -->
<div class="modal" id="deleteMemberForm">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">회원 탈퇴</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<b>회원 탈퇴 후 복구는 불가능합니다. <br> 정말로 탈퇴하시겠습니까? </b> <br><br>
<form action="<%=contextPath %>/delete.me" method="post">
<input type="hidden" name="userId" value="<%=userId%>">
<table>
<tr>
<td>비밀번호 입력</td>
<td><input type="password" name="userPwd" required></td>
</tr>
</table>
<br>
<button type="submit" class="btn btn-danger" onclick="return deleteMember();">탈퇴</button>
</form>
<script>
function deleteMember(){
if($("input[name=userPwd]").val() != "<%=userPwd%>"){
alert("비밀번호가 틀렸습니다.");
return false;
}
}
</script>
</div>
</div>
</div>
</div>
MyPageController
- servlet 파일로 작성한다.
- url로 마이페이지를 직접 요청할 수 있다. 이땐 로그인을 하기 전에 요청 시엔 메인페이지로 이동시키고,
로그인한 후에 요청 시엔 마이페이지로 이동시킨다.
@WebServlet("/myPage.me")
public class MyPageController extends HttpServlet {
private static final long serialVersionUID = 1L;
public MyPageController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// session의 속성값에 loginUser가 null일 때
if(session.getAttribute("loginUser") == null) {
// alert메시지 띄우고, 요청을 redirect하기
session.setAttribute("alertMsg", "로그인 후 이용해주세요.");
response.sendRedirect(request.getContextPath());
} else {
// null이 아닐 때 요청을 myPage로 보내고 request와 response를 forward하기
request.getRequestDispatcher("views/member/myPage.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MemberUpdateController
- myPage에서 정보 변경 시 Controller
- post 방식으로 요청 받았으므로 인코딩 설정해야 한다.
- 요청받은 값들을 Parameter로 받아 가공한다.
- 갱신된 회원정보를 Service로 보낸다.
- Service에서 돌려받은 결과를 가지고 사용자가 보게 될 view를 지정한다.
@WebServlet("/update.me")
public class MemberUpdateController extends HttpServlet {
private static final long serialVersionUID = 1L;
public MemberUpdateController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
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");
String interest = "";
if(interestArr != null) {
interest = String.join(", ", interestArr);
}
Member m = new Member(userId, userName, phone, email, address, interest);
Member updateMem = new MemberService().updateMember(m);
if(updateMem == null) { // 회원정보 수정 실패
request.setAttribute("errorMsg", "회원정보수정에 실패하였습니다.");
request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
} else { // 회원정보 수정 성공
HttpSession session = request.getSession();
session.setAttribute("loginUser", updateMem);// 동일 키값으로 값 대입 시 덮어쓰기됨
session.setAttribute("alertMsg", "회원정보가 수정되었습니다.");
response.sendRedirect(request.getContextPath()+"/myPage.me");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MemberUpdatePwdController
- myPage에서 비밀번호 변경 시 Controller
- post 방식으로 요청 받았으므로 인코딩 설정해야 한다.
- 요청받은 값들을 Parameter로 받아 가공한다.
- 갱신된 회원정보를 Service로 보낸다.
- Service에서 돌려받은 결과를 가지고 사용자가 보게 될 view를 지정한다.
@WebServlet("/updatePwd.me")
public class MemberUpdatePwdController extends HttpServlet {
private static final long serialVersionUID = 1L;
public MemberUpdatePwdController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userId = request.getParameter("userId");
String userPwd = request.getParameter("userPwd");
String updatePwd = request.getParameter("updatePwd");
Member updateMem = new MemberService().updatePwdMember(userId, userPwd, updatePwd);
HttpSession session = request.getSession();
if(updateMem == null) {
session.setAttribute("alertMsg", "비밀번호 변경에 실패하였습니다.");
} else {
session.setAttribute("loginUser", updateMem);
session.setAttribute("alertMsg", "비밀번호가 변경되었습니다.");
}
response.sendRedirect(request.getContextPath()+"/myPage.me");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MemberDeleteController
- myPage에서 회원 탈퇴 시 Controller
- post 방식으로 요청 받았으므로 인코딩 설정해야 한다.
- 요청받은 값들을 Parameter로 받아 가공한다.
- 로그인 회원의 아이디 정보 얻어오는 방법 2가지
· 방법① form에서 hidden으로 userId 보내기
· 방법② session에 담긴 loginUser 객체에 있는 userId 꺼내오기
- 결과값이 있을 때 removeAttribute() 메소드를 사용하여 session에 회원정보 객체만 삭제한다.
invalidate() 메소드를 사용하면 session이 초기화되고 alert까지 초기화된다.
@WebServlet("/delete.me")
public class MemberDeleteController extends HttpServlet {
private static final long serialVersionUID = 1L;
public MemberDeleteController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userPwd = request.getParameter("userPwd");
// 로그인한 회원의 아이디 정보 얻어오기
// 방법1. form에서 hidden으로 보내기
// String userId = request.getParameter("userId");
// 방법2. session에 담겨있는 loginUser(로그인한 회원정보) 객체에 있는 아이디 꺼내오기
HttpSession session = request.getSession();
// session에서 값을 꺼내오면 object 타입으로 가져와지므로 Member로 형변환해야한다.
String userId = ((Member)session.getAttribute("loginUser")).getUserId();
int result = new MemberService().deleteMember(userId, userPwd);
if(result > 0) {
session.setAttribute("alertMsg", "회원 탈퇴되었습니다.");
// invalidate() 메소드를 사용하면 session이 초기화되므로 alert 메세지까지 초기화된다.
// removeAttribute() 메소드를 사용해서 회원정보객체만 삭제한다.
session.removeAttribute("loginUser");
response.sendRedirect(request.getContextPath());
} else {
request.setAttribute("loginUser", result);
request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MemberService
-회원 정보 수정
public Member updateMember(Member m) {
Connection conn = JDBCTemplate.getConnection();
Member updateMem = null;
int result = new MemberDao().updateMember(conn, m);
if(result > 0) {
JDBCTemplate.commit(conn);
// db에는 데이터가 변경되었지만 session에 담겨있는 loginUser의 객체 정보는
// 갱신되지 않았으므로 이를 처리해줘야 한다.
updateMem = new MemberDao().selectMember(conn, m.getUserId());
} else {
JDBCTemplate.rollback(conn);
}
JDBCTemplate.close(conn);
return updateMem;
}
- 비밀번호 변경
public Member updatePwdMember(String userId, String userPwd, String updatePwd) {
Connection conn = JDBCTemplate.getConnection();
int result = new MemberDao().updatePwdMember(conn, userId, userPwd, updatePwd);
Member updateMem = null;
if(result > 0) {
JDBCTemplate.commit(conn);
// 갱신된 회원정보 조회해오기
updateMem = new MemberDao().selectMember(conn, userId);
} else {
JDBCTemplate.rollback(conn);
}
JDBCTemplate.close(conn);
return updateMem;
}
- 회원 탈퇴
public int deleteMember(String userId, String userPwd) {
Connection conn = JDBCTemplate.getConnection();
int result = new MemberDao().deleteMember(conn, userId, userPwd);
// 탈퇴한 회원은 로그아웃까지 진행(회원정보를 갱신할 필요가 없다)
if(result > 0) {
JDBCTemplate.commit(conn);
} else {
JDBCTemplate.rollback(conn);
}
JDBCTemplate.close(conn);
return result;
}
MemberDao
- 갱신된 회원 조회
public Member selectMember(Connection conn, String userId) {
// select문 - ResultSet 객체를 불러와서 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;
}
- 회원 정보 수정
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;
}
- 비밀번호 변경
public int updatePwdMember(Connection conn, String userId, String userPwd, String updatePwd) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("updatePwdMember");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, updatePwd);
pstmt.setString(2, userId);
pstmt.setString(3, userPwd);
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTemplate.close(pstmt);
}
return result;
}
- 회원 탈퇴
public int deleteMember(Connection conn, String userId, String userPwd) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("deleteMember");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
pstmt.setString(2, userPwd);
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTemplate.close(pstmt);
}
return result;
}
member-mapper
- xml 파일로 작성한다.
- updateMember
<entry key="updateMember">
UPDATE MEMBER
SET USER_NAME = ?
, PHONE = ?
, EMAIL = ?
, ADDRESS = ?
, INTEREST = ?
, MODIFY_DATE = SYSDATE
WHERE USER_ID = ?
</entry>
- selectMember
<entry key="selectMember">
SELECT *
FROM MEMBER
WHERE USER_ID = ?
AND STATUS = 'Y'
</entry>
- updatePwdMember
<entry key="updatePwdMember">
UPDATE MEMBER
SET USER_PWD = ? <!-- updatePwd -->
, MODIFY_DATE = SYSDATE
WHERE USER_ID = ?
AND USER_PWD = ? <!-- userPwd -->
</entry>