😎 STS3 Spring 쇼핑몰

STS3 쇼핑몰 프로젝트[13] 마이페이지 내 정보 보기, 내 정보 수정

개발자 린다씨 2022. 8. 2. 18:26
반응형

순서

0. 마이페이지 폼 만들기(jsp, css) 

1. MemberController.java에 마이페이지 폼으로 이동하기 위한 코드 추가

2. MemberMapper.xml에 내 정보 수정을 위한 sql 작성

3. MemberMapper.java, MemberService.java, MemberServiceImpl.java 코드 작성

4. MemberController.java에 수정하기 버튼 클릭 시 실행될 로직 작성

5. 마이페이지 내 정보 수정 <script> 추가

6. 테스트

0. 마이페이지 폼 만들기(jsp, css)

src/main/webapp/WEB-INF/views/member 아래 마이페이지 폼인 mypage_info.jsp를 생성합니다.

mypage_info.jsp

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link href="${path}/resources/css/mypage/mypage.css" rel="stylesheet"/>
	<title>내 정보 보기</title>
</head>
<body>
	<jsp:include page="../common/header.jsp"/>
	<div class="container">
		<div class="topic">마이페이지</div>
		<div class="content">
			<input type="radio" name="slider" checked id="info"> 
			<input type="radio" name="slider" id="modify"> 
			<input type="radio" name="slider" id="pass"> 
			<input type="radio" name="slider" id="delete"> 
			<div class="list">
				<label for="info" class="info"> 
					<i class="fa fa-info-circle" aria-hidden="true"></i>
					<span class="title">내 정보 보기</span>
				</label> 
				<label for="modify" class="modify"> 
					<span class="icon">
						<i class="fa fa-pen" aria-hidden="true"></i>
					</span> 
					<span class="title">내 정보 수정</span>
				</label> 
				<label for="pass" class="pass"> 
					<span class="icon">
						<i class="fa fa-unlock-alt" aria-hidden="true"></i>
					</span> 
					<span class="title">비밀번호 변경</span>
				</label> 
				<label for="delete" class="delete"> 
					<span class="icon">
						<i class="fa fa-minus-circle" aria-hidden="true"></i>
					</span> 
					<span class="title">회원 탈퇴</span>
				</label> 
				
				<div class="slider"></div>
			</div>
			<div class="text-content2">
				<div class="info text">
					<div class="title">'${ member.name }'님의 상세 정보</div>
					<p>
						아이디 : ${ member.id }<br><br>
						이름 : ${ member.name }<br><br>
						성별 : <c:if test="${ member.gender eq 'M' }">
								남자								
							</c:if>
							<c:if test="${ member.gender eq 'F' }">
								여자							
							</c:if>
							<c:if test="${ member.gender eq 'N' }">
								선택X								
							</c:if><br><br>
						이메일 : ${ member.email }<br><br>
						전화번호 : ${ member.phone }<br><br>
						주소 : ${ member.address }<br><br>
						상세 주소 : ${ member.address2 }
					</p>
				</div>
				
				<div class="modify text">
					<div class="title">'${ member.name }'님의 정보 수정</div>
					<form method="post" action="/member/updateMember" class="visibility" id="modifyForm">
						<p>
							아이디 : ${ member.id }<input type="hidden" name="id" value="${ member.id }"><br>
							<br>이름 : <input type="text" name="name" value="${ member.name }"><br>
							<br><span class="gender-details">
								<c:if test="${ member.gender eq 'M'}">
						            <input type="radio" name="gender" id="dot-1" value="M" checked>
						            <input type="radio" name="gender" id="dot-2" value="F">
						            <input type="radio" name="gender" id="dot-3" value="N">
								</c:if>
								<c:if test="${ member.gender eq 'F'}">
						            <input type="radio" name="gender" id="dot-1" value="M">
						            <input type="radio" name="gender" id="dot-2" value="F" checked>
						            <input type="radio" name="gender" id="dot-3" value="N">
								</c:if>
								<c:if test="${ member.gender eq 'N'}">
						            <input type="radio" name="gender" id="dot-1" value="M">
						            <input type="radio" name="gender" id="dot-2" value="F">
						            <input type="radio" name="gender" id="dot-3" value="N"checked>
								</c:if>
			          			<span class="category">
					            	성별 :&nbsp;
							         <label for="dot-1">
							            <span class="dot one"></span>
							            <span class="gender">남자</span>
							         </label>
							         <label for="dot-2">
							            <span class="dot two"></span>
							            <span class="gender">여자</span>
							         </label>
							         <label for="dot-3">
							            <span class="dot three"></span>
							            <span class="gender">선택X</span>
							         </label>
			          			</span>
		        			</span><br>
							이메일 : <input type="email" name="email" value="${ member.email }"><br>
							<br>전화번호 : <input type="tel" name="phone" value="${ member.phone }"><br>
							<br>주소 : <input type="text" id="colFormLabelLg3" onclick="execPostCode();" name="address" value="${ member.address }"><br>
							<br>상세 주소 : <input type="text" name="address2" value="${ member.address2 }"><br><br>
						
						
							<input type="button" value="수정하기" class="btn" id="modifyBtn"> 
					</form>
				</div>
				
</body>
</html>

mypage.css

더보기
@charset "UTF-8";

@import
	url('https://fonts.googleapis.com/css2?family=Gowun+Dodum&family=IBM+Plex+Sans+KR:wght@200;300;400&family=Noto+Serif+KR:wght@500&display=swap');

* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Gowun Dodum', sans-serif;
}

body {
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
}

.container {
	max-width: 950px;
	width: 100%;
	padding: 40px 50px 40px 40px;
	background: #fff;
	margin: 0 20px;
	border-radius: 12px;
	box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}

.container .topic {
	font-size: 30px;
	font-weight: bold;
	margin-bottom: 5px;
}

.content {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.content .list {
	display: flex;
	flex-direction: column;
	width: 20%;
	margin-right: 50px;
	position: relative;
}

.content .list label {
	height: 60px;
	font-size: 14px;
	font-weight: 500;
	line-height: 60px;
	cursor: pointer;
	padding-left: 25px;
	transition: all 0.5s ease;
	color: #333;
	z-index: 12;
}

#info:checked ~ .list label.info, #modify:checked ~ .list label.modify,
	#pass:checked ~ .list label.pass, #delete:checked ~ .list label.delete{
	color: #fff;
}

.content .list label:hover {
	color: #99004d;
}

.content .slider {
	position: absolute;
	left: 0;
	top: 0;
	height: 60px;
	width: 100%;
	border-radius: 12px;
	background: #99004d;
	transition: all 0.4s ease;
}

#info:checked ~ .list .slider {
	top: 0;
}

#modify:checked ~ .list .slider {
	top: 60px;
}

#pass:checked ~ .list .slider {
	top: 120px;
}

#delete:checked ~ .list .slider {
	top: 180px;
}

.content .text-content2 {
	width: 80%;
	height: 100%;
}

.content .text {
	display: none;
}

.content .text .title {
	font-size: 30px;
	margin-bottom: 30px;
	font-weight: 500;
}

.content .text p {
	text-align: justify;
}

.content .text-content2 .home {
	display: block;
}

#info:checked ~ .text-content2 .info, #modify:checked ~ .text-content2 .modify,
	#pass:checked ~ .text-content2 .pass, #delete:checked ~ .text-content2 .delete{
	display: block;
}

#modify:checked ~ .text-content2 .info, #pass:checked ~ .text-content2 .info,
	#delete:checked ~ .text-content2 .info{
	display: none;
}

.content input {
	display: none;
}

.visibility input{
	display: inline;
	height: 25px;
	width: 30%;
	outline: none;
	border-radius: 5px;
	padding-left: 5px;
	border: 1px solid #ccc;
	border-bottom-width: 2px;
	transition: all 0.3s ease;
}

.visibility input:focus{
	border-color: #99004d;
}

a{
	text-decoration: none;
}

form .category {
	display: flex;
	margin: 5px 0;
}

form input[type="radio"] {
	display: none;
}

form .category label {
	display: flex;
	align-items: center;
	cursor: pointer;
}

form .category label .dot {
	height: 18px;
	width: 18px;
	border-radius: 50%;
	margin-right: 5px;
	background: #d9d9d9;
	border: 5px solid transparent;
	transition: all 0.3s ease;
}

#dot-1:checked ~ .category label .one, #dot-2:checked ~ .category label .two,
	#dot-3:checked ~ .category label .three {
	background: #99004d;
	border-color: #d9d9d9;
}

#deleteBtn{
	border: none;
	outline: none;
  	box-shadow: none;
	background-color: white;
}

#modifyBtn{
	border: none;
	outline: none;
  	box-shadow: none;
	background-color: white;
}

form input[type="submit"] {
	border: none;
	outline: none;
  	box-shadow: none;
  	background-color: white;
}

form input[type="submit"]:hover {
	color: #99004d;
}

/* 유효성 검사 문구 */
.final_pw_ck{
    display: none;
}

내 정보 보기
내 정보 수정

1. MemberController.java에 마이페이지 폼으로 이동하기 위한 코드 추가

폼 생성 이후 MemberController.java에 마이페이지 버튼 클릭 시 마이페이지 폼으로 이동시키기 위한 코드를 추가합니다.

/* 마이페이지로 이동 */
@RequestMapping(value = "/mypage_info", method = RequestMethod.GET)
public void myinfoPOST() {
	logger.info("마이페이지 진입!");
}

2. MemberMapper.xml에 내 정보 수정을 위한 sql 작성

MemberMapper.xml에 내 정보 수정을 위한 쿼리문을 작성합니다. 

<!-- 내 정보 수정 -->
<update id="updateMember">
  	update member
	set name=#{name}, phone=#{phone}, email=#{email}, gender=#{gender}, address=#{address}, address2=#{address2}
	where id=#{id}
</update>

3. MemberMapper.java, MemberService.java, MemberServiceImpl.java 코드 작성

3-1. MemberMapper.java

MemberMapper.xml과의 연동을 위해 MemberMapper.java에 아래의 내용을 추가합니다.

/* 내 정보 수정  */
public int updateMember(MemberVO member);

3-2. MemberService.java

MemberService.java 인터페이스에 아래의 내용을 추가합니다.

/* 내 정보 수정 */
public int updateMember(MemberVO member) throws Exception;

3-3. MemberServiceImpl.java

MemberServiceImpl.java 클래스에 내 정보 수정에 사용될 로직을 추가합니다.

/* 내 정보 수정 */
@Override
public int updateMember(MemberVO member) throws Exception {
	return membermapper.updateMember(member);
}

4. MemberController.java에 수정하기 버튼 클릭 시 실행될 로직 작성

다음으로 MemberController.java 클래스에 아래의 내용을 추가합니다.

/* 내 정보 수정 */
@PostMapping("/updateMember")
public String updateMemberPOST(@ModelAttribute MemberVO member, RedirectAttributes rttr, Model model)
		throws Exception {
	logger.info("updateMemberPOST.........." + member);

	int result = memberService.updateMember(member);
	MemberVO loginUser = memberService.login(member);

	model.addAttribute("member", loginUser);
	// 해당 메서드가 작업을 정상적으로 수행했음을 알리는 메시지를 mypage_info.jsp로 전송하는 코드
	rttr.addFlashAttribute("modify_result", result);
	return "redirect:/member/mypage_info";
}

5. 마이페이지 내 정보 수정 <script> 추가

5-1. "회원 정보 수정 완료"

수정 성공 시 내 정보 보기 화면으로 이동하면서 "회원 정보 수정 완료"라는 경고창이 뜨게 하는 <script> 문을 추가해줍니다.

<script>
/* 수정 성공 이벤트 */
	let modify_result = '${modify_result}'
	if(modify_result == 1){
		alert("회원 정보 수정 완료");
	}
</script>

5-2. 주소 API

주소 수정을 위해 회원가입 때 사용했던 주소 API <script> 문을 추가해줍니다.

<!-- 주소 API 가져오기 -->
<script src=http://dmaps.daum.net/map_js_init/postcode.v2.js?autoload=false></script>
	<script>   
		function execPostCode() {
			daum.postcode.load(function() {
				new daum.Postcode({
				   oncomplete : function(data) {
				   // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
				               
				   // 각 주소의 노출 규칙에 따라 주소를 조합
				   // 내려오는 변수가 값이 없을 땐 공백('')값을 가지므로, 이를 참고
				    var addr = ''; // 주소 변수
				               
				    // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져옴
				    if(data.userSelectedType == 'R'){
				    // 사용자가 도로명 주소를 선택했을 경우
				        addr = data.roadAddress;
				     } else {
				        // 사용자가 지번 주소를 선택했을 경우
				        addr = data.jibunAddress;
				    }
				               
				    // 주소 정보를 해당 필드에 넣음.
				    document.getElementById('colFormLabelLg3').value = addr;
				               
				    // 커서를 주소 필드로 이동
				    document.getElementById("colFormLabelLg3").focus();
				               
				    }
				}).open();	
			});
		}
      </script>

5-3. 내 정보 수정 버튼 클릭 이벤트

수정하기 버튼 클릭 시 해당 내용이 controller에 전송될 수 있는 <script> 문을 추가합니다.

/* 수정 버튼 */
$("#modifyBtn").on("click", function(e) {
	e.preventDefault();
	$("#modifyForm").submit();
});

mypage_info.jsp

더보기
<div class="container">
		<div class="topic">마이페이지</div>
		<div class="content">
			<input type="radio" name="slider" checked id="info"> 
			<input type="radio" name="slider" id="modify"> 
			<input type="radio" name="slider" id="pass"> 
			<input type="radio" name="slider" id="delete"> 
			<div class="list">
				<label for="info" class="info"> 
					<i class="fa fa-info-circle" aria-hidden="true"></i>
					<span class="title">내 정보 보기</span>
				</label> 
				<label for="modify" class="modify"> 
					<span class="icon">
						<i class="fa fa-pen" aria-hidden="true"></i>
					</span> 
					<span class="title">내 정보 수정</span>
				</label> 
				<label for="pass" class="pass"> 
					<span class="icon">
						<i class="fa fa-unlock-alt" aria-hidden="true"></i>
					</span> 
					<span class="title">비밀번호 변경</span>
				</label> 
				<label for="delete" class="delete"> 
					<span class="icon">
						<i class="fa fa-minus-circle" aria-hidden="true"></i>
					</span> 
					<span class="title">회원 탈퇴</span>
				</label> 
				
				<div class="slider"></div>
			</div>
			<div class="text-content2">
				<div class="info text">
					<div class="title">'${ member.name }'님의 상세 정보</div>
					<p>
						아이디 : ${ member.id }<br><br>
						이름 : ${ member.name }<br><br>
						성별 : <c:if test="${ member.gender eq 'M' }">
								남자								
							</c:if>
							<c:if test="${ member.gender eq 'F' }">
								여자							
							</c:if>
							<c:if test="${ member.gender eq 'N' }">
								선택X								
							</c:if><br><br>
						이메일 : ${ member.email }<br><br>
						전화번호 : ${ member.phone }<br><br>
						주소 : ${ member.address }<br><br>
						상세 주소 : ${ member.address2 }
					</p>
				</div>
				<script>
					/* 수정 성공 이벤트 */
					let modify_result = '${modify_result}'
					if(modify_result == 1){
						alert("회원 정보 수정 완료");
					}
				</script>
				
				<div class="modify text">
					<div class="title">'${ member.name }'님의 정보 수정</div>
					<form method="post" action="/member/updateMember" class="visibility" id="modifyForm">
						<p>
							아이디 : ${ member.id }<input type="hidden" name="id" value="${ member.id }"><br>
							<br>이름 : <input type="text" name="name" value="${ member.name }"><br>
							<br><span class="gender-details">
								<c:if test="${ member.gender eq 'M'}">
						            <input type="radio" name="gender" id="dot-1" value="M" checked>
						            <input type="radio" name="gender" id="dot-2" value="F">
						            <input type="radio" name="gender" id="dot-3" value="N">
								</c:if>
								<c:if test="${ member.gender eq 'F'}">
						            <input type="radio" name="gender" id="dot-1" value="M">
						            <input type="radio" name="gender" id="dot-2" value="F" checked>
						            <input type="radio" name="gender" id="dot-3" value="N">
								</c:if>
								<c:if test="${ member.gender eq 'N'}">
						            <input type="radio" name="gender" id="dot-1" value="M">
						            <input type="radio" name="gender" id="dot-2" value="F">
						            <input type="radio" name="gender" id="dot-3" value="N"checked>
								</c:if>
			          			<span class="category">
					            	성별 :&nbsp;
							         <label for="dot-1">
							            <span class="dot one"></span>
							            <span class="gender">남자</span>
							         </label>
							         <label for="dot-2">
							            <span class="dot two"></span>
							            <span class="gender">여자</span>
							         </label>
							         <label for="dot-3">
							            <span class="dot three"></span>
							            <span class="gender">선택X</span>
							         </label>
			          			</span>
		        			</span><br>
							이메일 : <input type="email" name="email" value="${ member.email }"><br>
							<br>전화번호 : <input type="tel" name="phone" value="${ member.phone }"><br>
							<br>주소 : <input type="text" id="colFormLabelLg3" onclick="execPostCode();" name="address" value="${ member.address }"><br>
							<br>상세 주소 : <input type="text" name="address2" value="${ member.address2 }"><br><br>
						
						
							<input type="button" value="수정하기" class="btn" id="modifyBtn"> 
					</form>
				</div>
				<!-- 주소 API 가져오기 -->
				<script src=http://dmaps.daum.net/map_js_init/postcode.v2.js?autoload=false></script>
				<script>   
				   function execPostCode() {
				      daum.postcode.load(function() {
				         new daum.Postcode({
				            oncomplete : function(data) {
				               // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
				               
				               // 각 주소의 노출 규칙에 따라 주소를 조합
				               // 내려오는 변수가 값이 없을 땐 공백('')값을 가지므로, 이를 참고
				               var addr = ''; // 주소 변수
				               
				               // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져옴
				               if(data.userSelectedType == 'R'){
				                  // 사용자가 도로명 주소를 선택했을 경우
				                  addr = data.roadAddress;
				               } else {
				                  // 사용자가 지번 주소를 선택했을 경우
				                  addr = data.jibunAddress;
				               }
				               
				               // 주소 정보를 해당 필드에 넣음.
				               document.getElementById('colFormLabelLg3').value = addr;
				               
				               // 커서를 주소 필드로 이동
				               document.getElementById("colFormLabelLg3").focus();
				               
				            }
				         }).open();
				
				      });
				   }
				   
				   /* 수정 버튼 */
				   $("#modifyBtn").on("click", function(e) {
						e.preventDefault();
						$("#modifyForm").submit();
					});
				   
				</script>
              </div>
             </div>

6. 테스트

수정하기 버튼 클릭 시

 

반응형