오늘은 회원 정보 수정을 구현해보려고 한다.
이메일에는 아직 횟수제한을 걸어놓지 않았기 때문에, 따로 유효성 검사는 하지않고 이메일 양식만 체크하고,
닉네임은 ajax를 사용해서 비동기방식으로 유효성 검사를 했다.
간단하게 count 후 , if문 -> alert창으로 유효성 검사를 할 수도 있겠지만..
ajax가 아직 어렵게 느껴져서 익숙해지기 위해 일부로 사용해봤다.
회원정보 수정페이지에서, 아이디와 닉네임 이메일이 있는데, 아이디는 수정불가로 구현했다.
닉네임 수정 기능을 추가하기전에,
글 , 댓글작성 시에 제목,작성자명,내용으로 insert되는 로직을
제목 , 작성자명(닉네임) , 내용 , ID (input type="hidden") 로 바꾸어줬다.
글수정,삭제 등의 권한을 작성자명이 아닌, ID값으로 바꿔서 닉네임 변경 시에도 계정에 권한이 유지되도록 했다.
한두가지 컬럼을 추가하고, Mapper,VO를 수정하고, 프론트단을 손보면 되는 작업이였지만,
이미 어느정도 구현을 한 상태라서 꽤나 손이 많이 갔다.
설계의 중요성을 느꼇다.. 같은 일을 여러번 하지 않으려면 .. ㅜㅜ
Mapper.xml
<update id="infoUpdate">
update MP_MEMBER set MEMBER_NAME = #{memberName}, MEMBER_EMAIL = #{memberEmail} where MEMBER_ID = #{memberId}
</update>
<select id="nameCheck" parameterType="kr.co.vo.MemberVO" resultType="int">
select count(*) from MP_MEMBER where MEMBER_NAME = #{memberName}
</select>
쿼리는 어렵지않다. ID ( 세션의 값) 를 ㅣ기준으로 이메일과 닉네임을 수정한다.
아래의 쿼리는 유효성 체크인데, 닉네임을 카운트해서 0이 아닌지로 유효성 체크를 한다.
DAO,DAOImlp
public void infoUpdate(MemberVO memberVO)throws Exception;
public int nameCheck(MemberVO memberVO)throws Exception;
@Override
public void infoUpdate(MemberVO memberVO)throws Exception{
Map<String,Object> map = new HashMap<String, Object>();
map.put("memberEmail", memberVO.getMemberEmail());
map.put("memberName", memberVO.getMemberName());
map.put("memberId", memberVO.getMemberId());
sqlsession.update("memberMapper.infoUpdate", map);
}
@Override
public int nameCheck(MemberVO memberVO)throws Exception{
return sqlsession.selectOne("memberMapper.nameCheck", memberVO);
}
쿼리에 필요한 파라미터를 map으로 넣어줬다. (아래처럼 그냥 VO로 넣어줘도 된다.)
Service, ServiceImpl
public void infoUpdate(MemberVO memberVO)throws Exception;
public int nameCheck(MemberVO memberVO)throws Exception;
@Override
public void infoUpdate(MemberVO memberVO)throws Exception{
memberDAO.infoUpdate(memberVO);
}
@Override
public int nameCheck(MemberVO memberVO)throws Exception{
return memberDAO.nameCheck(memberVO);
}
Controller
//회원정보수정뷰
@RequestMapping(value="/infoView", method=RequestMethod.GET)
public String infoView() throws Exception{
return"/member/infoView";
}
//회원정보수정로직
@RequestMapping(value="/infoUpdate", method=RequestMethod.POST)
public String infoUpdate(HttpServletRequest request,HttpSession session,MemberVO memberVO,Model model,RedirectAttributes rttr)throws Exception{
memberService.infoUpdate(memberVO);
session.invalidate();
rttr.addFlashAttribute("msg", "정보 수정이 완료되었습니다. 다시 로그인해주세요.");
return"redirect:/member/loginView";
}
회원정보를 수정하면 세션을 없애고(로그아웃) 다시 로그인을 하도록 만들었다.
(바뀐 회원정보에 따라 세션값을 변경해야 하는데 애를 먹어서 일단 이렇게 구현, 후에 수정 예정이다.)
//닉네임 유효성 체크
@RequestMapping(value="/nameCheck",method=RequestMethod.POST)
@ResponseBody
public String idCnt(@RequestBody String filterJSON,HttpServletResponse response,Model model)throws Exception{
JSONObject resMap = new JSONObject();
try {
ObjectMapper mapper = new ObjectMapper();
MemberVO searchVO = (MemberVO) mapper.readValue(filterJSON, new TypeReference<MemberVO>(){});
int nameCnt = memberService.nameCheck(searchVO);
resMap.put("res", "ok");
resMap.put("nameCnt", nameCnt);
}catch(Exception e) {
System.out.println(e.toString());
resMap.put("res","error");
}
response.setContentType("text/html: charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(resMap);
return null;
}
[스프링]회원가입(ajax 유효성 검사,비밀번호 암호화) - 로그인1 :: 간편 웹프로그래밍 (tistory.com)
해당 유효성검사는 이전 글에 작성해놓았다..
좀 더 간단하게 로직을 짤 수도 있을 것 같은데 아직 연습이 많이 필요하다.
infoView.jsp
script>
$(documenct).ready(function(){
});
function duplicate(){
var memberName=$("#memberName").val();
var submitObj = new Object();
submitObj.memberName=memberName;
$.ajax({
url : "/member/nameCheck",
type : "POST",
contentType : "application/json; charset-utf-8",
data : JSON.stringify(submitObj),
dataType : "json"
}).done(function(resMap) {
if (resMap.res == "ok") {
if (resMap.nameCnt == 0) {
alert("사용할 수 있는 닉네임입니다.");
$("#memberName_yn").val("Y");
} else {
alert("중복된 닉네임입니다.");
$("#memberName_yn").val("N");
}
}
}).fail(function(e) {
alert("등록 시도에 실패하였습니다." + e);
}).always(function() {
pass = false;
});
}
function fnSubmit(){
var email_rule = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;
if ($("#memberName").val() == null || $("#memberName").val() == "") {
alert("닉네임을 입력해주세요.");
$("#memberName").focus();
return false;
}
if ($("#memberEmail").val() == null || $("#memberEmail").val() == "") {
alert("이메일을 입력해주세요.");
$("#memberEmail").focus();
return false;
}
if(!email_rule.test($("#memberEmail").val())){
alert("이메일을 형식에 맞게 입력해주세요. ex) 1234@naver.com");
$("#memberEmail").focus();
return false;
}
if ($("#memberName_yn").val() != 'Y') {
alert("닉네임 중복체크를 눌러주세요.");
$("#memberName_yn").focus();
return false;
}
if (confirm("수정하시겠습니까?")) {
$("#infoView").submit();
return false;
}
}
</script>
유효성 검사 script
<!-- Page Heading -->
<h1 class="h3 mb-4 text-gray-800">회원 정보 수정</h1>
<div class="row">
<div class="col-lg-6">
<!-- Circle Buttons -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">ID , Email</h6>
</div>
<div class="card-body">
<form id="infoView" action="/member/infoUpdate" method="POST" class="form-signup form-user panel-body" autocomplete="off">
<input type="hidden" id="memberName_yn" name="memberName_yn" value="N"/>
<fieldset>
<div class="form-group">
<label class="control-label" for="fullName">ID</label>
<input type="text" name="memberId" class="form-control input-sm" value="${login.memberId}" id="memberId" readonly>
</div>
<div class="form-group">
<label class="control-label" for="nickname">닉네임</label>
<a href="#" class="btn btn-outline-dark btn-icon-split" style="text-align:center;" onclick="duplicate(); return false;">
<span class="icon text-white-30">
<i class="fas fa-check"></i>
</span>
<span class="text">중복체크</span>
</a>
<input type="text" name="memberName" class="form-control input-sm" placeholder="닉네임" value="${login.memberName}" id="memberName">
</div>
<div class="form-group">
<label class="control-label" for="nickname">이메일</label>
<input type="email" name="memberEmail" value="${login.memberEmail}" placeholder="이메일" class="form-control input-sm" id="memberEmail">
</div>
</fieldset>
<button class="btn btn-primary btn-block" type="button" onclick="fnSubmit(); return false;">정보 수정</button>
</form>
</div>
</div>
<!-- Brand Buttons -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">PassWord , Delete</h6>
</div>
<div class="card-body">
<a href="/member/pwUpdateView" class="btn btn-info btn-block">비밀번호 변경</a>
<a href="/member/memberDelete" class="btn btn-default btn-block">회원 탈퇴</a>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">다른 사항이 들어갈 공간</h6>
</div>
<div class="card-body">
<p>추가할공간( 포인트, 추천 등)</p>
</div>
</div>
</div>
</div>
어서 프로젝트를 마치고, javascript 공부와 리액트 공부를 해야겠다.. ㅜㅜ
프로젝트하면서 프론트에서 가장 애를 먹는다...
중복버크 버튼을 누르면 duplicate() 함수로 연결되고,
정보수정버튼을 누르면 fnsubmit() 함수로 연결된다.
memberEmail_yn 이 Y가 아니면 false를 리턴해서 멈추고,
memberEmial을 Y로 만들기 위해선 duplicate()의 ajax함수를 통해,
입력한 닉네임이 select문의 count에서 0이되어야 Y가 된다.
input hidden으로 들어가있는 memberName_yn은 기본값이 N이다.
결과
1장은 회원 정보 수정 뷰,
2장은 중복체크다.
글을 쓰면서 생각난건데, 회원정보 수정의 이메일에도 이메일 인증을 넣어야겠다..
다음 글은 비밀번호 수정과 암호화, 비밀번호를 통한 회원탈퇴를 구현해보려고 한다.
'SPRING > IceWater Community' 카테고리의 다른 글
[스프링] 회원정보수정 - 회원탈퇴 (ajax) (0) | 2021.09.25 |
---|---|
[스프링] 회원정보수정 - 비밀번호 (ajax) (0) | 2021.09.24 |
[스프링]비밀번호 찾기 구현 (1) | 2021.09.24 |
[스프링] 아이디찾기 구현 (1) | 2021.09.24 |
[스프링]회원가입 이메일인증 구현 (1) | 2021.09.19 |