본문 바로가기

수업 복습하기/개인 페이지 만들기

[포트폴리오] 개인페이지 제작기 03

728x90
728x90

이렇게 작성이 필요하지만 우선 우리는 Mapper를 만들어 보도록 하자

우선 boardmapper(인터페이스),boardmapper.xml,boardVO을 따라서 member영역의 필요한 파일들을 만들었다.

 MemberMapper(인터페이스) + MemberMapper.xml + MemberVO 까지 만들었고,

그 이후에 ex00\src\test\java\org\zerock\mapper\project1\MemberMapperTest.java라는 이치에

 

MemberMapperTest.java를 junittest파일로 해서 새로 작성하였다.

insert가 되는지부터 차근차근 코딩을 시작했다.

(여기서는 직접 값을 넣어서, 우선 sql에 값이 들어가는지부터 확인하였다.)

	@Test
	public void insertTest() {
		MemberVO vo = new MemberVO();
		vo.setId("newMember" + (new Date().getTime()));
		vo.setPassword("newpassword");
		vo.setAddress("seoul");
		vo.setEmail("member1@naver.com");
		
		int cnt = mapper.insert(vo);
		
		assertEquals(1, cnt);
	
	}

그리고서, 테스트를 돌릴 때마다, id가 유일한 값으로 나타나게 하기 위해서, member 뒤에 date+ gettime()을 더해서, 매번 테스트를 돌릴 때마다 id에 유일한 값이 들어가게 설정하였다.

1밀리세컨드안에, insert랑 select랑 같이 test를 진행해보자

 

그다음에 update까지 넣었는데, mypassword + email + inserted가 변하게만드는 것이었다.

 

delete메소드 = assertnull 이미 삭제되어야하니까, 아무것도 값이 들어가있으면 안된다가 true여야한다!

인서트한 것을 바로 지워버리는 것!

 

지우기 전의 list를 가져오고, 지우기 후의 list를 가져와서, 둘의 차이가 1이나는지 확인해보자

식의 위치는 delete위 아래로 한개씩!

지우기 전의 식에는, insert한 아이템들이 모두 다 null이 아니어서 notnull식이 true가 되어야한다.

지운 후에는, mapper.list()를 가져와서, 1개의 차이가 나는지 확인해보면된다.

 

//다음 service만들기!

나는 아직도 서비스를 왜 만들어야하는지 아직도 ..진짜모르겠다..

이제 이론 공부하다 보면 알겠지...?

package org.zerock.service.project1;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.project1.MemberVO;
import org.zerock.mapper.project1.MemberMapper;

import lombok.Setter;

@Service
public class MemberService {

	@Setter (onMethod_ = @Autowired)
	private MemberMapper mapper;
	
	public MemberVO read(String id) {
		return mapper.select(id);
	}
	public boolean register(MemberVO member) {
		return mapper.insert(member) ==1;
	}
	
	public boolean modify(MemberVO member) {
		return mapper.update(member)==1;
	}
	public boolean remove(String id ) {
		return mapper.delete(id) ==1;
	}
	public List<MemberVO> getList(){
		return mapper.list();
	}
}

 

tag에 signup페이지로 연결되는 부분을 추가했다.

그리고, signup.jsp와 membercontroller부분을 제작하기시작했다.

만약, 멤버 객채가 null이라면, 우선 회원가입을 넘어갈 수 있게하고, m이 있는 값이라면, 중복된 아이디 입니다.뜨게만든다.

get방식과 post방식의 명확한 이해가 더 필요할 것 같다.

인터넷 서칭 결과, 만약 내가 로그인을 했는데, get방식이면, 주소창에 내 ID와 비밀번호가 노출이 되면서 보안에 취약한 문제가 생길 수 있으니, post방식으로 내보내서 보안을 유지하게 하는 것이다라는 것을 배웠다.

 

와 추가정보

F3을 누르면 그 메소드로 이동이되니까 빠른 이동이 가능하다는거 ~

 

중복된 아이디로 가입했을 때, 해결하는 방법 정리하기

memberservice에 가서

	public boolean register(MemberVO member) {
		try{
			return mapper.insert(member) ==1;
		}catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

와 같이, 수정을 넣었다. service에서 exception이 났을 때 , false가 돌아오게 만들었다.

memberVO에서 불러온 멤버가, null이면 입력가능한 아이디가 되는것이고,

그게 아니라면 중복된 아이디라고 알람이 뜨게 만들었다.

 

	@PostMapping("/signup")
	public String signup(@ModelAttribute("member") MemberVO member, RedirectAttributes rttr, Model model) {
		MemberVO m = service.read(member.getId());

		if (m == null) {
			boolean ok = service.register(member);

			if (ok) {
				rttr.addFlashAttribute("result", "회원가입이 완료되었습니다.");
				return "redirect:/board/list";
			} else {
				return "redirect:/member/signup";
			}
		} else {
			model.addAttribute("alertMessage", "중복된 아이디 입니다.");
			return null;
		}
	}

모델이 필요하니까 모델을 파라미터로 넣고, jsp에서  alertmessage있음에 따라서, 보여주고 안보여주고를 나눴다

(코드를짜는방식이 여러개가있지만 선생님은 이런방식으로 했다.) -> 이 alertmessage에 따라서 jsp에서 어떤 컴포넌트는 보여주고, 안보여주고의 형식으로 나누었다.

<div class="container">
		<div class="row">
			<div class="col">
				<h1>회원 가입</h1>
				<c:if test="${not empty alertMessage}">
					<div class="alert alert-dark">${alertMessage }</div>
				</c:if>

 

실제로는 signup(@modelAttribute부분이 생략되어있는건데,

우리예전에 이 부분이 생략되어있는데, 표에 없는거면 requestparam아니면 modelattribute anyotherargument...

모델이 이미 붙어있는데 else부분에, 이름이 붙어있는게 memberVO로 붙어있으니까, member라고 사용하고싶으면

@modelAttribute("member")을 넣었다. 이거에 따라서 signup jsp에 뒤에 value값을 붙였다.

이에따라서 누릴수있는 이득=> 이 아이디로 가입하려고 했을 때, 중복된 아이디입니다 라고 .alertMessage가 위에 뜨지만, 안에 있는 내용은 날아가지 않고 그대로 유지가 되게 할 수 있어서, 아이디만 원하는대로 바꾸면 문제 없이 회원가입을 할 수 있게 된다.

 

/ 이제 수정 삭제를 가능하게 하기 위해서, 본인이 만든 게시물을 삭제할 수 있게 해야 하기 때문에, 로그인 기능부터 다시 수정이 들어간다.

		<li class="nav-item active">
			<a class="nav-link" href="${loginUrl }">목록</a>
		</li>

 

/navbar 태그에, 페이지 추가 하고

member에 로그인 페이지를 만들어보도록 하자 기본적인 login.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"%>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<link rel="stylesheet" href="<%=request.getContextPath()%>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

<title>Insert title here</title>
</head>
<body>
	<b:navBar></b:navBar>
	<!-- .container>.row>.col>h1{로그인} -->
	<div class="container">
		<div class="row">
			<div class="col">
				<h1>로그인</h1>
				<!-- form>.form-group*2>label[for=input$]+input.form-control[name][required]^button.btn.btn-outline-primary -->
				<form method="post">
					<div class="form-group">
						<label for="input1"></label>
						<input type="text" class="form-control" name="id" required="">
					</div>
					<div class="form-group">
						<label for="input2"></label>
						<input type="text" class="form-control" name="password" required="">
					</div>
					<button class="btn btn-outline-primary"></button>
				</form>
			</div>
		</div>
	</div>

	<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>

이제 이 jsp를 위한 컨트롤러를 또 제작해보도록 하자

@PostMapping("/login")
	public String login(String id, String password, HttpSession session) {
		// service 사용해서 아이디로 멤버vo 얻고
		MemberVO vo = service.read(id);
		
		if (vo == null) {
			return null;
		}

		// 얻어온 멤버vo의 패스워드와 입력한 패스워드가 같은 지 확인
		boolean correctPassword = password.equals(vo.getPassword());

		// 멤버vo가 널이거나 패스워드가 다르면 로그인 실패
		if (!correctPassword) {
			return null;
		}

		// 멤버vo가 널이 아니고 패스워드가 일치하면 로그인 성공
		// 로그인 성공
		session.setAttribute("loggedInMember", vo);
		System.out.println(session.getAttribute("loggedInMember"));
		return "redirect:/board/list";
	}

jsp에서는 id와 password란 이름으로 넘어오기 때문에, controller에서는 id와 password를편하게 사용하면 된다.

return 을 null로 하는 값은, 그냥 그 페이지에 남아있게 하는 방법이다. -> 이렇게 하려면, void 에서 String으로 바뀌어야 한다.

로그인이 성공되었다는 말을 띄우고 싶다면 redirect attribute로 넣어주면된다.

그리고 젤 중요한 것

이제 로그인에 성공했으면, 다음 요청부터는 로그인 된 사람인지 아닌지 판단이 되어야 한다.

-> 이럴 때는 Session객체를 활용하면 되는데, vo객체에서 내가 원하는 이름을 넣은 후에,

login메소드에 httpsession 파라미터를 넣어준다.

 

System.out.println(session.getAttribute("loggedInMember")); 이 식을 통해서, 잘 되고있는지 확인해보자

이식을 넣고, 로그인을 해보면 console창에 

MemberVO(id=myid4, password=asdf, email=myid4@gmail.com, address=seoul, inserted=2022-01-06T00:17:55)

이렇게 로그인이 잘 된 것을 확인해볼 수 있다. 로그인 성공~

 

/로그아웃 작성

이번에도 navbar에 가서 로그아웃 url전송되게만드는것부터 시작

<c:url value="/member/logout" var="logoutUrl"></c:url>

<li class="nav-item active">
	<a class="nav-link" href="${logoutUrl }">로그아웃</a>
</li>

그리고, 회원가입과 로그인은 로그인 되어있을 때 보이지 않게해야하고, 로그인되어있을 때는 로그아웃만 보이게 해야한다. 이것은 session attribute로 담아놨기 때문에, c:if로 test해서, 상황에 따라서 보이고, 안보이게 해야한다.

<c:if test="${empty sessionScope.loggedInMember }">
	<li class="nav-item active">
		<a class="nav-link" href="${signupUrl }">회원가입</a>
	</li>
	<li class="nav-item active">
		<a class="nav-link" href="${loginUrl }">로그인</a>
	</li>
	</c:if>
	<c:if test="${not empty sessionScope.loggedInMember  }">
		<li class="nav-item active">
			<a class="nav-link" href="${logoutUrl }">로그아웃</a>
		</li>
	</c:if>

navBar.tag는 c:if와같은형태로 넣어서 수정! 잘돌아간다~

 

/자 이제 로그아웃 진짜로 만들어보자

posting방식에 상관없이 로그아웃되게 만들게 할거니까 그냥 requestmapping으로 진행!

 

@RequestMapping("/logout")
	public String logout(HttpSession session) {
		// 세션 invalidate
		session.invalidate();
		// /board/list redirect
		return "redirect:/board/list";
	}

session.invalidate()뭐하는거더라..다시찾아봐야겠는걸..? 아마..로그인되어있는값을 빼내는거가튼데..끙

오 맞는것같다 로그아웃누르니까 세션값이 빠져서 다시 tag에 로그인과 회원가입 으로 가는 버튼나왔다!

 

/회원정보수정하기 만들자

 

 <c:url value="/member/info" var="memberInfoUrl"></c:url>
 
 <li class="nav-item active">
        <a class="nav-link" href="${memberInfoUrl }">회원정보보기</a>
      </li>

이제 이것에 맞는 controller 메소드 작성하자

중요한건 info같은경우에는, 로그인되어있는 사람의 정보만 수정 가능하게 해야하기 때문에

이런거는 session attribute가 있고 없고로 구분하게 하기로 했으니까 

	@GetMapping("/info")
	public String info(HttpSession session) {

		MemberVO vo = (MemberVO) session.getAttribute("loggedInMember");

		// 로그아웃 상태
		if (vo == null) {
			return "redirect:/member/login";
		}
        
		// 로그인 상태일 때
		return null;
	}

이제 이거에 맞는 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"%>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<link rel="stylesheet" href="<%=request.getContextPath()%>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

<title>Insert title here</title>
</head>
<body>
	<b:navBar></b:navBar>
	<!-- .container>.row>.col>h1{회원정보} -->
	<div class="container">
		<div class="row">
			<div class="col">
				<h1>회원정보</h1>
				<!-- form>.form-group*4>label[for=input$]+input.form-control[name][value] -->
				<form method="post" id="infoForm">
          <div class="form-group">
            <label for="input1">아이디</label>
            <input type="text" required id="input1" class="form-control" name="id" value="${sessionScope.loggedInMember.id }" readonly>
          </div>
          <div class="form-group">
            <label for="input2">패스워드</label>
            <input type="password" required id="input2" class="form-control" name="password" value="${sessionScope.loggedInMember.password }">
          </div>
          <div class="form-group">
            <label for="input3">이메일</label>
            <input type="email" required id="input3" class="form-control" name="email" value="${sessionScope.loggedInMember.email }">
          </div>
          <div class="form-group">
            <label for="input4">주소</label>
            <input type="text" required id="input4" class="form-control" name="address" value="${sessionScope.loggedInMember.address }">
          </div>
					<!-- button.btn.btn-outline-secondary{수정}+button.btn.btn-outline-danger{삭제} -->
					<button class="btn btn-outline-secondary" >수정</button>
					<button class="btn btn-outline-danger">삭제</button>
				</form>
			</div>
		</div>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>

value값을 session에 있는 값으로 가져와서 수정하고싶은 부분만 편하게 수정 후 완료버튼을 누를 수 있게 만든게 포인트

또 아이디같은 경우에는, 수정되면 안되니까, readonly로 읽는것만 가능하게 했다.

또또 꼭 입력하게 해야하기 때문에 모든 input값에다가 required를 넣어 필수로 만들었다.

 

/이제는 수정버튼을 눌렀을 때, 어느 경로로 넘어가게 할 지 확인하자.

post방식으로 jsp에 수정하고, controller에 또 postmapping을 추가하자

@PostMapping("/info")
	public String info(MemberVO member, HttpSession session, RedirectAttributes rttr) {
		MemberVO vo = (MemberVO) session.getAttribute("loggedInMember");

		// 로그아웃 상태
		if (vo == null) {
			return "redirect:/member/login";
		}
        
		// 로그인된 상태
		boolean ok = service.modify(member);
		
		if (ok) {
			rttr.addFlashAttribute("result", "회원 정보가 변경되었습니다.");
			session.setAttribute("loggedInMember", service.read(member.getId()));
		} else {
			rttr.addFlashAttribute("result", "회원 정보가 변경되지 않았습니다.");
		}

		return "redirect:/board/list";
	}

우선 getmapping의 로그아웃상태 코드 써놓은거 가져와서 좀 수정을 할건데 젤 중요한게

parameter에 MemberVO값이 vo로 같은 상태니까 우선 member로 수정했다는 것

 

service에서 modify member를 넣어서 수정해주면, 

모달창 뜨게해주는 값이 우리는 result로 넣어놨다. 모달창 있는 창이 list니까 글로 return 시키면 모달창 뜬다~

사실문제가생길일이 없기는 한데 혹시 모르니까 회원정보가 변경되지 않았을 상황까지 추가했다.

 

session.setAttribute("loggedInMember", service.read(member.getId()));

이 식이 기존에 있던 세션에 값에 새로운 수정된 회원정보를 덮어씌울 수 있도록 하는 값이다.

(여기서부터 약간 난관..?)

 

 

/이제 여기서부터 script를 활용해서, modifybutton과 removeButton을 눌렀을 때, 어떻게 진행될지의 식을 써보자!

(와 나 j쿼리랑 자바스크립트 부분 공부안한거 너무티난다.. 선생님이 식쓰시는데 무슨말인지 이해안가ㅠㅠ큰일났다)

<script>
      $(document).ready(
          function() {
        	  const infoForm = $("#infoForm");
          
              // 수정버튼 또는 삭제버튼 클릭 시 form의 action 속성값 변경
              $("#modifyButton").click(function(e) {
                e.preventDefault();
                infoForm.attr("action", "");
                infoForm.submit();
              });

              $("#removeButton").click(function(e) {
                e.preventDefault();
                if (confirm("탈퇴하시겠습니까?")) {
                  infoForm.attr("action", "remove");
                  infoForm.submit();
                }
              })
          });
 </script>

우선삭제버튼눌러보니까 삭제는 잘 되었고, 이제 controller가서 삭제되었을 때 어디로 연결될지, 사이트연결해주면 된다.

 

/여기서부터 membercontroller

로그인되어있는 상태인지, 로그아웃되어있는 상태인지 봐야하기 때문에,

로그아웃상태인지 확인하는 

		MemberVO vo = (MemberVO) session.getAttribute("loggedInMember");

		// 로그아웃 상태
		if (vo == null) {
			return "redirect:/member/login";

이만큼의 식을 포함시키면서 전체 식은 

@PostMapping("/remove")
	public String remove(String id, HttpSession session, RedirectAttributes rttr) {
		MemberVO vo = (MemberVO) session.getAttribute("loggedInMember");

		// 로그아웃 상태
		if (vo == null) {
			return "redirect:/member/login";
		}
		// 로그인된 상태
		service.remove(id);
		session.invalidate();
		rttr.addFlashAttribute("result", "회원 탈퇴하였습니다");
		return "redirect:/board/list";
	}

삭제할 때, 회원 탈퇴하였다고 message도 잘떳고, 로그인도 안되어진다.

db에서도, 지워지는 것까지 확인했다@

 

오늘의 수업은 여기까지 길고도 험난한 길이었다..넘어려어어엉

728x90