국비 81 - 회원정보 수정(스프링)

냐아암·2023년 8월 15일
0

국비

목록 보기
92/114

📍 @SessionAttributes

  • Model에 세팅된 값의 key와 {}에 작성된 값이 일치하면 session scope로 이동
  • Session으로 올려둔 값을 해당 클래스에서 얻어와 사용 가능

🔑 회원 정보 수정 후 동기화 작업 필수!!

<li> <a href="/myPage/info">내 정보</a> </li>

MyPageController

package edu.kh.project.myPage.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import edu.kh.project.member.model.dto.Member;
import edu.kh.project.myPage.model.service.MyPageService;

@SessionAttributes({"loginMember"})
// 1) Model에 세팅된 값의 key와 {}에 작성된 값이 일치하면 session scope로 이동
// 2) Session으로 올려둔 값을 해당 클래스에서 얻어와 사용 가능하게 한다.
//		-> @SessionAttribute(key)로 사용 !!!s 안 붙음!!!

@RequestMapping("/myPage") // /myPage로 시작하는 요청을 모두 받음
@Controller // 요청, 응답 제어 클래스 + bean 등록
public class MyPageController {
	
	@Autowired // MyPageService의 자식 MyPageServiceImpl 의존성 주입 (DI)
	private MyPageService service;
	
	// 내정보
	@GetMapping("/info")
	public String info() {
		// ViewResolver
		return "myPage/myPage-info";
	}
	
	// 프로필
	@GetMapping("/profile")
	public String profile() {
		// ViewResolver
		return "myPage/myPage-profile";
	}
	
	// 비번 변경
	@GetMapping("/changePw")
	public String changePw() {
		// ViewResolver
		return "myPage/myPage-changePw";
	}
	
	// 회원 탈퇴
	@GetMapping("/secession")
	public String secession() {
		// ViewResolver
		return "myPage/myPage-secession";
	}
	
	// 회원 정보 수정
	@PostMapping("/info")
	public String info(Member updateMember, String[] memberAddress
						, @SessionAttribute("loginMember") Member loginMember // s 안 붙이기 주의 !!!!!!!!!!!!!!!!!!!!!!!!!!
						, RedirectAttributes ra) {
		
		// ----------------- 매개변수 설명 -------------------------------------------
		// Member updateMember : 수정할 닉네임, 전화번호 담긴 커맨드 객체
		// String[] memberAddress : name="memberAddress" 인 input 3개의 값(주소)
		
		// @SessionAttribute("loginMember") Member loginMember
		// : Session에서 얻어온 "loginMember"에 해당하는 객체를
		//   매개변수 Member loginMember에 저장
		
		// RedirectAttributes ra : 리다이렉트 시 값 전달용 객체(request)
		// ------------------------------------------------------------------------
		
		// 주소를 하나로 합치기(a^^^b^^^c)
		String addr = String.join("^^^", memberAddress);
		updateMember.setMemberAddress(addr);
		
		// 로그인한 회원의 번호를 updateMember에 추가
		updateMember.setMemberNo(loginMember.getMemberNo());
		
		// DB에 회원 정보 수정 (UPDATE 호출)
		int result = service.updateInfo(updateMember);
		
		String message = null;
		
		if(result>0) { // 성공
			message = "회원정보가 수정되었습니다.";
			
			// 세션에 로그인된 회원 정보도 수정(동기화)
			loginMember.setMemberNickname(updateMember.getMemberNickname());
			loginMember.setMemberTel(updateMember.getMemberTel());
			loginMember.setMemberAddress(updateMember.getMemberAddress());
		} else { // 실패
			message = "회원정보 수정 실패";
		}
		
		ra.addFlashAttribute("message" , message);
		
		return "redirect:info"; // 상대경로
		// redirect:/myPage/info // 절대경로
	}
	
	

}

MyPageService

/** 회원정보 수정 서비스
	 * @param updateMember
	 * @return result
	 */
	int updateInfo(Member updateMember);

MyPageServiceImpl

// 스프링에서는 트랜잭션을 처리할 방법을 지원해줌.(코드기반, 선언적)
	// 1) <tx:advice> -> AOP를 이용한 방식(XML에 작성)

	// 2) @Transactional 어노테이션을 이용한 방식(클래스 또는 인터페이스에 작성)
	// - 인터페이스를 구현한 클래스로 선언된 빈은 인터페이스 메소드에 한해서 트랜잭션이 적용됨
	// * 트랜잭션 처리를 위해서는 트랜잭션 매니저가 bean으로 등록되어 있어야 함. 
	//   -> root-context.xml 작성

	// 정상 여부는 RuntimeException이 발생했는지 기준으로 결정되며, 
	// RuntimeException 외 다른 Exception(대표적으로 SQLException 등)에도 트랜잭션 롤백처리를 적용하고 싶으면 
	// @Transactional의 rollbackFor 속성을 활용하면 된다
	
	// 회원 정보 수정 서비스
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public int updateInfo(Member updateMember) {
		
		int result = dao.updateInfo(updateMember);
		
		return result;
	}

MyPageDAO

/** 회원 정보 수정 DAO
	 * @param updateMember
	 * @return result
	 */
	public int updateInfo(Member updateMember) {
		
		// return sqlSession.update("namespace.id", 전달할 값);
		return sqlSession.update("myPageMapper.updateInfo", updateMember);
	}

mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="myPageMapper">

	<!-- SELECT 일 때만 사용하는 resultMap -->
	<resultMap type="Member" id="member_rm">
     
     	<id property="memberNo" column="MEMBER_NO" />
     	<result property="memberEmail" column="MEMBER_EMAIL"/>
     	<result property="memberPw" column="MEMBER_PW"/>
     	<result property="memberNickname" column="MEMBER_NICKNAME"/>
     	<result property="memberTel" column="MEMBER_TEL"/>
     	<result property="memberAddress" column="MEMBER_ADDR"/>
     	<result property="profileImage" column="PROFILE_IMG"/>
     	<result property="enrollDate" column="ENROLL_DATE"/>
     	<result property="memberDeleteFlag" column="MEMBER_DEL"/>
     	<result property="authority" column="AUTHORITY"/>
     	
     </resultMap>
     
     
     
     <!-- 회원정보 수정 -->
     <update id="updateInfo" parameterType="Member">
     	UPDATE MEMBER SET
		MEMBER_NICKNAME = #{memberNickname},
		MEMBER_TEL = #{memberTel},
		MEMBER_ADDR = #{memberAddress}
		WHERE MEMBER_NO = #{memberNo}
     </update>



</mapper>

📍 ${fn:split(문자열, 구분자)

  • 문자열을 구분자로 나누어 배열 형태로 변환
    ${fn:split(loginMember.memberAddress, '^^^')[0]}
<%@ 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 lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>마이페이지</title>

    <link rel="stylesheet" href="/resources/css/myPage/myPage-style.css">

</head>
<body>
    <main>
        <jsp:include page="/WEB-INF/views/common/header.jsp" />

        <section class="myPage-content">

            <jsp:include page="/WEB-INF/views/myPage/sideMenu.jsp" />

            <section class="myPage-main">

                <h1 class="myPage-title">내 정보</h1>
                <span class="myPage-subject">원하는 회원 정보를 수정할 수 있습니다.</span>

                <%-- 현재 페이지 http://localhost/myPage/info 
                    제일 뒤에 info 지우고
                    action에 작성된 경로 추가
                --%>

                <%-- 상대경로 --%>
                <form action="info" method="POST" name="myPageFrm">

                    <div class="myPage-row">
                        <label>닉네임</label>
                        <input type="text" name="memberNickname"  maxlength="10" value="${loginMember.memberNickname}">
                    </div>

                    <div class="myPage-row">
                        <label>전화번호</label>
                        <input type="text" name="memberTel"  maxlength="11" value="${loginMember.memberTel}">
                    </div>


                    <%-- ${fn:split(loginMember.memberAddress, '^^^')[0]}
                    ${fn:split(loginMember.memberAddress, '^^^')[1]}
                    ${fn:split(loginMember.memberAddress, '^^^')[2]} --%>

                    <%-- 
                        ${fn:split(문자열, 구문자)}
                        문자열을 구분자로 나누어 배열 형태로 반환
                     --%>

                    <c:set var="addr" value="${fn:split(loginMember.memberAddress, '^^^')}"/>

                    <div class="myPage-row info-title">
                        <span>주소</span>
                    </div>

                    <div class="myPage-row info-address">
                        <input type="text" name="memberAddress" placeholder="우편번호" value="${addr[0]}"  id="sample6_postcode">
                        <button type="button"  onclick="sample6_execDaumPostcode()">검색</button>
                    </div>

                    <div class="myPage-row info-address">
                        <input type="text" name="memberAddress"  placeholder="도로명/지번 주소" value="${addr[1]}"  id="sample6_address">                
                    </div>

                    <div class="myPage-row info-address">
                        <input type="text" name="memberAddress"  placeholder="상세 주소" value="${addr[2]}"  id="sample6_detailAddress">                
                    </div>

                    <button class="myPage-submit">수정하기</button>
                </form>

            </section>

        </section>

    </main>
    <jsp:include page="/WEB-INF/views/common/footer.jsp" />

    <!-- 다음 주소 api 추가 -->
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>

    <script>
        function sample6_execDaumPostcode() {
            new daum.Postcode({
                oncomplete: function(data) {
                    // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                    // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                    // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                    var addr = ''; // 주소 변수

                    //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                    if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                        addr = data.roadAddress;
                    } else { // 사용자가 지번 주소를 선택했을 경우(J)
                        addr = data.jibunAddress;
                    }

                    // 우편번호와 주소 정보를 해당 필드에 넣는다.
                    document.getElementById('sample6_postcode').value = data.zonecode;
                    document.getElementById("sample6_address").value = addr;
                    // 커서를 상세주소 필드로 이동한다.
                    document.getElementById("sample6_detailAddress").focus();
                }
            }).open();
        }
    </script>
    
</body>
</html>
profile
개발 일지

0개의 댓글