2020년 02월 05일
업데이트:
마이페이지
header.jsp
헤더에 유저 이름을 클릭하면 마이페이지로 이동할 수 있도록 a 태그 href 속성에 경로 추가, 세션에 올라와있는 loginMember
에 있는 memberName 값을 불러온다.
<a class="nav-link" href="${contextPath}/member2/mypage" style="display:inline">${loginMember.memberName }</a>
MemberController2.java
mypage.jsp 화면을 보여주기 위해 Controller를 작성한다.
@RequestMapping("mypage")
public String myPage() {
return "member/mypage";
}
mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>내정보</title>
<style>
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button
{
-webkit-appearance: none;
margin: 0;
}
#content-main {
min-height: 770px;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp" />
<div class="container mt-5 pt-5" id="content-main">
<div class="row">
<div class="col-sm-9">
<h1>My Page</h1>
<hr>
<div class="bg-white rounded shadow-sm container p-3">
<form method="POST" action="updateAction" name="updateForm" onsubmit="return updateValidate();" class="form-horizontal" role="form">
<!-- 아이디 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>아이디</h6>
</div>
<div class="col-md-6">
<h5 id="id">${loginMember.memberId}</h5>
</div>
</div>
<!-- 이름 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>이름</h6>
</div>
<div class="col-md-6">
<h5 id="name">${loginMember.memberName}</h5>
</div>
</div>
<!-- 전화번호 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<label for="phone1">전화번호</label>
</div>
<!-- 전화번호1 -->
<c:set var="phone" value="${fn:split(loginMember.memberPhone,'-')}"></c:set>
<div class="col-md-3">
<select class="custom-select" id="phone1" name="phone1">
<option <c:if test="${phone[0] == '010'}"> selected </c:if> >>010</option>
<option <c:if test="${phone[0] == '011'}"> selected </c:if> >>011</option>
<option <c:if test="${phone[0] == '016'}"> selected </c:if> >>016</option>
<option <c:if test="${phone[0] == '017'}"> selected </c:if> >>017</option>
<option <c:if test="${phone[0] == '019'}"> selected </c:if> >>019</option>
</select>
</div>
<!-- 전화번호2 -->
<div class="col-md-3">
<input type="number" class="form-control phone"
id="phone2" name="phone2" maxlength="4" value="${phone[1]}">
</div>
<!-- 전화번호3 -->
<div class="col-md-3">
<input type="number" class="form-control phone"
id="phone3" name="phone3" maxlength="4" value="${phone[2]}">
</div>
</div>
<!-- 이메일 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<label for="memberEmail">Email</label>
</div>
<div class="col-md-6">
<input type="email" class="form-control" id="email"
name="memberEmail" value="${loginMember.memberEmail }">
</div>
</div>
<br>
<c:set var="address" value="${fn:split(loginMember.memberAddress, ',')}"></c:set>
<!-- 주소 -->
<!-- 오픈소스 도로명 주소 API -->
<!-- https://www.poesis.org/postcodify/ -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<label for="postcodify_search_button">우편번호</label>
</div>
<div class="col-md-3">
<input type="text" name="post" id="post"
class="form-control postcodify_postcode5" value="${address[0]}">
</div>
<div class="col-md-3">
<button type="button" class="btn btn-success"
id="postcodify_search_button">검색</button>
</div>
</div>
<div class="row mb-3 form-row">
<div class="col-md-3">
<label for="address1">도로명 주소</label>
</div>
<div class="col-md-9">
<input type="text" class="form-control postcodify_address"
name="address1" id="address1" value="${address[1]}">
</div>
</div>
<div class="row mb-3 form-row">
<div class="col-md-3">
<label for="address2">상세주소</label>
</div>
<div class="col-md-9">
<input type="text" class="form-control postcodify_details"
name="address2" id="address2" value="${address[2]}">
</div>
</div>
<!-- 관심분야 -->
<hr class="mb-4">
<div class="row">
<div class="col-md-3">
<label>관심 분야</label>
</div>
<div class="col-md-9 custom-control custom-checkbox">
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="sports" value="운동" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="sports">운동</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="movie" value="영화" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="movie">영화</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="music" value="음악" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="music">음악</label>
</div>
<br>
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="cooking" value="요리" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="cooking">요리</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="game" value="게임" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="game">게임</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" name="memberInterest" id="etc" value="기타" class="form-check-input custom-control-input">
<label class="form-check-label custom-control-label"
for="etc">기타</label>
</div>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-success btn-lg btn-block" type="submit">수정</button>
</form>
</div>
</div>
<jsp:include page="sideMenu.jsp" />
</div>
</div>
<jsp:include page="../common/footer.jsp" />
<!-- 도로명 주소 API -->
<script src="//d1p7wdleee1q2z.cloudfront.net/post/search.min.js"></script>
<script>
// 도로명 주소 API
// 검색 단추를 누르면 팝업 레이어가 열리도록 설정한다.
$(function() {
$("#postcodify_search_button")
.postcodifyPopUp();
});
// 전화번호 숫자 4글자 이상 작성 방지
$(".phone").on("input", function() {
if ($(this).val().length > $(this).prop("maxLength")) {
$(this).val($(this).val().slice(0, $(this).prop("maxLength")));
}
});
// 각 유효성 검사 결과를 저장할 객체
var validateCheck = {
"phone2" : false,
"email" : false
};
// submit 동작
function updateValidate() {
var $phone2 = $("#phone2");
var $phone3 = $("#phone3");
var $email = $("#email");
// 전화번호 유효성 검사
var regExp1 = /^\d{3,4}$/; // 숫자 3~4 글자
var regExp2 = /^\d{4,4}$/; // 숫자 4 글자
if (!regExp1.test($phone2.val()) || !regExp2.test($phone3.val())) {
validateCheck.phone2 = false;
} else {
validateCheck.phone2 = true;
}
// 이메일 유효성 검사
var regExp3 = /^[\w]{4,}@[\w]+(\.[\w]+){1,3}$/;
if (!regExp3.test($email.val())) {
validateCheck.email = false;
} else {
validateCheck.email = true;
}
for ( var key in validateCheck) {
if (!validateCheck[key]) {
var str;
switch (key) {
case "phone2": str = "전화번호"; break;
case "email": str = "이메일"; break;
}
swal({icon : "warning", title : str + " 형식이 유효하지 않습니다."})
.then(function() {
var id = "#" + key;
$(id).focus();
});
return false;
}
}
$memberPhone = $("<input>", {
type : "hidden",
name : "memberPhone",
value : $("#phone1").val() + "-" + $("#phone2").val()
+ "-" + $("#phone3").val()
});
$memberAddress = $("<input>", {
type : "hidden",
name : "memberAddress",
value : $("#post").val() + "," + $("#address1").val() + ","
+ $("#address2").val()
});
$("form[name='updateForm']").append($memberPhone).append($memberAddress);
}
//******************** 전화번호 체크 ***************************
/* (function(){
$("#phone1 > option").each(function(index, item){
if("${phone[0]}" == $(item).text()) {
$(item).prop("selected", true);
}
});
})(); */
//******************** 전화번호 체크 ***************************
//******************** 관심 분야 체크 ***************************
(function(){
var interest = "${loginMember.memberInterest}".split(",");
$("input[name='memberInterest']").each(function(index, item){
if(interest.indexOf($(item).val()) != -1){
$(item).prop("checked", true);
}
})
})();
//******************** 관심 분야 체크 ***************************
</script>
</body>
</html>
회원 정보 수정
mypage.jsp
에서 form 태그 action 속성에 있는 태그 updateAction
경로를 Controller에 작성한다.
MemberContorller2.java
// 회원 정보 수정 Controller
@RequestMapping(value = "updateAction", method = RequestMethod.POST)
public String updateAction(@ModelAttribute Member updateMember, Model model,
@ModelAttribute(name = "loginMember", binding = false) Member loginMember, RedirectAttributes ra) {
updateMember.setMemberNo(loginMember.getMemberNo());
int result = service.updateAction(updateMember);
loginMember.setMemberPhone(updateMember.getMemberPhone());
loginMember.setMemberEmail(updateMember.getMemberEmail());
loginMember.setMemberAddress(updateMember.getMemberAddress());
loginMember.setMemberInterest(updateMember.getMemberInterest());
model.addAttribute("loginMember", loginMember);
if (result > 0) {
swalIcon = "success";
swalTitle = "회원 정보 수정 성공";
swalText = "회원 정보 수정이 완료되었습니다.";
} else {
swalIcon = "error";
swalTitle = "회원 정보 수정 실패";
swalText = "정보 수정 과정에서 문제가 발생했습니다.";
}
ra.addFlashAttribute("swalIcon", swalIcon);
ra.addFlashAttribute("swalTitle", swalTitle);
ra.addFlashAttribute("swalText", swalText);
return "redirect:mypage";
}
- binding : 요청 파라미터를 해당 객체에 반영할지 결정한다. false : 미반영 / true : 반영
MemberService2.java (interface)
/** 회원정보 수정 Service
* @param updateMember
* @return result
*/
int updateAction(Member updateMember);
MemberService2Impl.java
// 회원가입 수정 Service 구현
@Override
@Transactional(rollbackFor = Exception.class)
public int updateAction(Member updateMember) {
return dao.updateAction(updateMember);
}
MemberDAO2.java
/** 회원정보 수정 DAO
* @param updateMember
* @return result
*/
public int updateAction(Member updateMember) {
return sqlSession.update("memberMapper2.updateAction", updateMember);
}
member-mapper2.xml
<!-- 회원 정보 수정 -->
<!-- 이메일, 전화번호, 주소 , 관심분야 -->
<update id="updateAction" parameterType="Member">
UPDATE MEMBER SET
MEMBER_EMAIL = #{memberEmail},
MEMBER_PHONE = #{memberPhone},
MEMBER_ADDR = #{memberAddress},
MEMBER_INTEREST = #{memberInterest}
WHERE MEMBER_NO = #{memberNo}
</update>
비밀번호 변경
비밀번호 변경은 마이페이지 내 사이드 메뉴에서 a 태그를 선택하면 비밀번호 변경 페이지로 전환된다.
sideMenu.jsp
<li class="list-group-item list-group-item-action"><a href="changePwd">비밀번호 변경</a></li>
MemberController2.java
// 비밀번호 변경 화면 전환용 Controller
@RequestMapping("changePwd")
public String changePwd() {
return "member/changePwd";
}
changePwd.jsp
<body>
<jsp:include page="../common/header.jsp"/>
<div class="container mt-5 pt-5" id="content-main">
<div class="row">
<div class="col-sm-9">
<h1>Change Password</h1>
<hr>
<div class="bg-white rounded shadow-sm container p-3">
<form method="POST" action="updatePwd" onsubmit="return validate();"
class="form-horizontal" role="form">
<!-- 아이디 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>아이디</h6>
</div>
<div class="col-md-6">
<h5 id="id">${loginMember.memberId}</h5>
</div>
</div>
<hr>
<!-- 현재 비밀번호 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>현재 비밀번호</h6>
</div>
<div class="col-md-6">
<input type="password" class="form-control" id="memberPwd" name="memberPwd">
</div>
</div>
<!-- 새 비밀번호 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>새 비밀번호</h6>
</div>
<div class="col-md-6">
<input type="password" class="form-control"
id="newPwd1" name="newPwd1">
</div>
</div>
<!-- 새 비밀번호 확인-->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>새 비밀번호 확인</h6>
</div>
<div class="col-md-6">
<input type="password" class="form-control"
id="newPwd2" name="newPwd2">
</div>
</div>
<hr class="mb-4">
<button class="btn btn-success btn-lg btn-block" type="submit">변경하기</button>
</form>
</div>
</div>
<jsp:include page="sideMenu.jsp"/>
</div>
</div>
<jsp:include page="../common/footer.jsp"/>
<script>
// submit 동작
function validate() {
// 비밀번호 유효성 검사
//영어 대,소문자 + 숫자, 총 6~12글자
var regExp = /^[A-Za-z0-9]{6,12}$/;
if(!regExp.test($("#newPwd1").val())){
alert("유효하지 않은 비밀번호 입니다.");
$("#newPwd1").focus();
return false;
}
if($("#newPwd1").val() != $("#newPwd2").val()){
alert("새 비밀번호가 일치하지 않습니다.");
$("#newPwd2").focus();
return false;
}
}
</script>
</body>
</html>
MemberController2.java
@RequestMapping(value="updatePwd", method = RequestMethod.POST)
public String updatePwd(@RequestParam("memberPwd") String memberPwd,
@RequestParam("newPwd1") String newPwd,
@ModelAttribute(name="loginMember", binding=false) Member loginMember
, RedirectAttributes ra) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("memberPwd", memberPwd);
map.put("newPwd", newPwd);
map.put("memberNo", loginMember.getMemberNo());
int result = service.updatePwd(map);
String url = null;
if(result > 0) {
swalIcon = "success";
swalTitle = "비밀번호 변경 성공";
swalText = "비밀번호가 성공적으로 변경되었습니다.";
url = "mypage";
}else {
swalIcon = "error";
swalTitle = "비밀번호 변경 실패";
swalText = "비밀번호 변경 과정에서 문제가 발생했습니다.";
url = "changePwd";
}
ra.addFlashAttribute("swalIcon", swalIcon);
ra.addFlashAttribute("swalTitle", swalTitle);
ra.addFlashAttribute("swalText", swalText);
return "redirect:" + url;
}
MemberService2.java (interface)
/** 비밀번호 변경 Service
* @param map
* @return result
*/
int updatePwd(Map<String, Object> map);
MemberService2Impl.java
// 비밀번호 변경 Service 구현
@Transactional(rollbackFor = Exception.class)
@Override
public int updatePwd(Map<String, Object> map) {
String savePwd = dao.selectPwd((int)map.get("memberNo"));
int result = 0;
if(savePwd != null) {
if(enc.matches((String)map.get("memberPwd"), savePwd)) {
String encPwd = enc.encode((String)map.get("newPwd"));
map.put("newPwd", encPwd);
result = dao.updatePwd(map);
}
}
return result;
}
MemberDAO2.java
/** 비밀번호 조회 DAO
* @param memberNo
* @return savePwd
*/
public String selectPwd(int memberNo) {
return sqlSession.selectOne("memberMapper2.selectPwd", memberNo);
}
/** 비밀번호 수정 DAO
* @param map
* @return result
*/
public int updatePwd(Map<String, Object> map) {
return sqlSession.update("memberMapper2.updatePwd", map);
}
member-mapper2.xml
<!-- 현재 비밀번호 조회 -->
<select id="selectPwd" parameterType="_int" resultType="string">
SELECT MEMBER_PWD FROM MEMBER
WHERE MEMBER_NO = #{memberNo}
</select>
<!-- 비밀번호 변경 -->
<update id="updatePwd" parameterType="map" >
UPDATE MEMBER SET
MEMBER_PWD = #{newPwd} <!-- map에 저장된 데이터의 key 값을 직접 작성 -->
WHERE MEMBER_NO = #{memberNo}
</update>
회원 탈퇴
sideMenu.jsp
<li class="list-group-item list-group-item-action"><a href="secession">회원 탈퇴</a></li>
MemberController2.java
// 회원 탈퇴 화면 전환용 Controller
@RequestMapping("secession")
public String secession() {
return "member/secession";
}
secession.jsp
<body>
<jsp:include page="../common/header.jsp"/>
<div class="container mt-5 pt-5" id="content-main">
<div class="row">
<div class="col-sm-offset-2 col-sm-9">
<h3>회원 탈퇴</h3>
<div class="bg-white rounded shadow-sm container p-3">
<form method="POST" action="deleteMember" onsubmit="return validate();"
class="form-horizontal" role="form">
<!-- 아이디 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>아이디</h6>
</div>
<div class="col-md-6">
<h5 id="id">${loginMember.memberId}</h5>
</div>
</div>
<!-- 비밀번호 -->
<div class="row mb-3 form-row">
<div class="col-md-3">
<h6>비밀번호</h6>
</div>
<div class="col-md-6">
<input type="password" class="form-control" id="currentPwd"
name="memberPwd">
</div>
</div>
<hr>
<div class="panel panel-default">
<div class="panel-body">
<div class="form-group pull-left">
<label class="control-label"> 회원 탈퇴 약관 </label>
<div class="col-xs-12">
<textarea class="form-control" readonly rows="10" cols="100">
제1조
이 약관은 샘플 약관입니다.
① 약관 내용 1
② 약관 내용 2
③ 약관 내용 3
④ 약관 내용 4
제2조
이 약관은 샘플 약관입니다.
① 약관 내용 1
② 약관 내용 2
③ 약관 내용 3
④ 약관 내용 4
</textarea>
</div>
<div class="checkbox pull-right">
<div class="custom-checkbox">
<div class="form-check">
<input type="checkbox" name="agree" id="agree"
class="form-check-input custom-control-input"> <br>
<label class="form-check-label custom-control-label"
for="agree">위 약관에 동의합니다.</label>
</div>
</div>
</div>
</div>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-success btn-lg btn-block" id="btn"
type="submit">탈퇴</button>
</form>
</div>
</div>
<jsp:include page="sideMenu.jsp"/>
</div>
</div>
<jsp:include page="../common/footer.jsp"/>
<script>
// submit 동작
function validate() {
if($("#currentPwd").val().trim().length == 0){
alert("비밀번호를 입력해주세요.");
return false;
}
if(!$("#agree").prop("checked")){
alert("약관에 동의해 주세요.");
return false;
}else{
return confirm("정말로 탈퇴하시겠습니까?");
}
}
</script>
</body>
MemberController2.java
@RequestMapping( value="deleteMember", method = RequestMethod.POST)
public String deleteMember(@RequestParam("memberPwd") String memberPwd,
@ModelAttribute(name="loginMember", binding=false) Member loginMember,
RedirectAttributes ra,
SessionStatus status) {
// 회원번호가 필요 == Session에 있는 loginMember에 저장되어있음
// --> @ModelAttribute("loginMember")를 통해서 얻어옴
int memberNo = loginMember.getMemberNo();
int result = service.deleteMember(memberPwd, memberNo);
String url = null;
if(result > 0) {
swalIcon = "success";
swalTitle = "회원 탈퇴 성공";
status.setComplete();
url = "/";
}else {
swalIcon = "error";
swalTitle = "회원 탈퇴 실패";
url = "secession";
}
ra.addFlashAttribute("swalIcon", swalIcon);
ra.addFlashAttribute("swalTitle", swalTitle);
return "redirect:" + url;
}
MemberService2.java
/** 회원탈퇴 Service
* @param memberPwd
* @param memberNo
* @return result
*/
int deleteMember(String memberPwd, int memberNo);
MemberService2Impl.java
// 회원탈퇴 Service 구현
@Transactional(rollbackFor = Exception.class)
@Override
public int deleteMember(String memberPwd, int memberNo) {
int result = 0;
String savePwd = dao.selectPwd(memberNo);
if (savePwd != null) {
if (enc.matches(memberPwd, savePwd)) {
result = dao.deleteMember(memberNo);
}
}
return result;
}
MemberDAO2.java
public int deleteMember(int memberNo) {
return sqlSession.update("memberMapper2.deleteMember", memberNo);
}
member-mapper2.xml
<!-- 회원 탈퇴 -->
<update id="deleteMember" parameterType="_int">
UPDATE MEMBER SET
MEMBER_STATUS = 'N'
WHERE MEMBER_NO = #{memberNo}
</update>
댓글남기기