📌 mypage.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- /springmvc1/src/main/webapp/WEB-INF/view/user/mypage.jsp --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My page</title>
<%-- --%>
<script type="text/javascript">
function disp_div(id, tab) {
$(".info").hide()
$(".tab").removeClass("select")
$("#" + id).show()
$("#" + tab).addClass("select")
}
function list_disp(id) {
$("#" + id).toggle()
}
</script>
<style type="text/css">
.select {
padding : 3px;
background-color : #0000ff;
}
.select>a {
color : #ffffff;
text-decoration : none;
font-weight : bold;
}
</style>
</head>
<body>
<table class="w3-table">
<tr><td id="tab1" class="tab select">
<a href="javascript:disp_div('minfo', 'tab1')">회원정보 보기</a></td>
<c:if test="${param.id != 'admin'}">
<td id="tab2" class="tab">
<a href="javascript:disp_div('oinfo', 'tab2')">주문정보 보기</a></td>
</c:if></tr>
</table>
<div id="oinfo" class="info" sytle="display: none; width:100%;">
<table class="w3-table">
<tr><th>주문번호</th><th>주문일자</th><th>총 주문금액</th></tr>
<c:forEach items="${salelist}" var="sale" varStatus="stat">
<tr><td align="center">
<a href="javascript:list_disp('saleLine${stat.index}')">${sale.saleid}</a></td>
<td align="center">
<fmt:formatDate value="${sale.saledate}" pattern="yyyy-MM-dd"/>
</td><td align="right">
<fmt:formatNumber value="${sale.total}" pattern="#,###"/>원</td></tr>
<tr id="saleLine${stat.index}" class="saleLine" style="display: none;">
<td colspan="3" align="center">
<table class="w3-table">
<tr><th width="25%">상품명</th><th width="25%">상품가격</th>
<th width="25%">구매수량</th><th width="25%">상품총액</th></tr>
<c:forEach items="${sale.itemList}" var="saleItem">
<tr><td class="title">${saleItem.item.name}</td>
<td>
<fmt:formatNumber value="${saleItem.quantity*saleItem.item.price}" pattern="#,###"/>원</td></tr></c:forEach>
</table></td></tr></c:forEach></table></div>
<div id="minfo" class="info">
<table class="w3-table">
<tr><td>아이디</td><td>${user.userid}</td></tr>
<tr><td>이름</td><td>${user.username}</td></tr>
<tr><td>우편번호</td><td>${user.postcode}</td></tr>
<tr><td>전화번호</td><td>${user.phoneno}</td></tr>
<tr><td>주소</td><td>${user.address}</td></tr>
<tr><td>이메일</td><td>${user.email}</td></tr>
<tr><td>생년월일</td><td><fmt:formatDate value="${user.birthday}" pattern="yyyy-MM-dd" /></td></tr>
</table><br>
<a href="update?id=${user.userid}">[회원정보 수정]</a>
<a href="password">[비밀번호 수정]</a>&bnsp;
<c:if test="${loginUser.userid != 'admin'}">
<a href="delete?id=${user.userid}">[회원탈퇴]</a>
</c:if>
<c:if test="${loginUser.userid == 'admin'}">
<a href="../admin/list">[회원목록]</a>
</c:if></div>
</body>
</html>
📌 UserLoginAspect.java 내용 추가하기
package aop;
import javax.servlet.http.HttpSession;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import exception.LoginException;
import logic.Cart;
import logic.User;
@Component //객체화
@Aspect //AOP 기능의 클래스
public class UserLoginAspect {
/*
* Pointcut : 핵심메서드의 선택 기준 설정
*
* execution(* controller.User*.loginCheck*(..)) && args(..,session) :
* controller 페키지의 클래스 중 User로 시작하는 클래스의 메서드 중 longinCheck로 시작하는 (..) 매개변수와 상관없이 모든 메서드
* args(..,session) :
* 매서드의 매개변수의 마지막 변수의 자료형이 HttpSession인 메서드를 선택.
* .. : 아무거나 상관없음
*
* Advice : AOP 메서드의 실행되는 시점 설정.
* 1. @Around : 핵심(Pointcut) 메서드 실행 전 후 AOP 메서드 실행
* ProceedingJoinPoint를 이용하여 전 후 를 구분함
* 2. @Before : 핵심 메서드 실행 전 AOP 메서드 실행
* 3. @After : 핵심 메서드 실행 후 AOP 메서드 실행
* 4. @AfterReturning : 핵심 메서드 실행 정상 종료 후 AOP 메서드 실행
* 5. @AfterThrowing : 핵심 메서드 실행 오류 종료 후 AOP 메서드 실행
*/
@Around("execution(* controller.User*.loginCheck*(..)) && args(..,session)")
public Object userLoginCheck(ProceedingJoinPoint joinPoint, HttpSession session) throws Throwable {
//joinPoint : 실행되어야 하는 메서드들의 순서를 관리 할 수 있는 객체
//session : Pointcut 메서드의 마지막 매개변수
User loginUser = (User)session.getAttribute("loginUser");
if(loginUser == null) { //로그인이 안된 경우
throw new LoginException("[userlogin]로그인 후 거래 하세요.", "login");
}
return joinPoint.proceed(); //다음번 메서드로 진행. 실행 전과 후를 나눠주는 역할
}
**@Around("execution(* controller.User*.idCheck*(..)) && args(..,id,session)")
public Object useridCheck(ProceedingJoinPoint joinPoint,String id, HttpSession session) throws Throwable {
User loginUser = (User)session.getAttribute("loginUser");
if(loginUser == null) {
throw new LoginException("[idCheck]로그인 후 거래하세요.", "login");
} else if(!loginUser.getUserid().equals(id) && !loginUser.getUserid().equals("admin")) {
throw new LoginException("[idCheck]본인만 거래 가능합니다.", "../item/list");
}
return joinPoint.proceed();
}**
}
📌 kiclayout.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}"/>
<%-- /springmvc1/src/main/webapp/layout/kiclayout.jsp --%>
<!DOCTYPE html>
<html>
<head>
<title><sitemesh:write property="title"/></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
html,body,h1,h2,h3,h4,h5 {font-family: "Raleway", sans-serif}
</style>
<sitemesh:write property="head"/>
</head>
<body class="w3-light-grey">
<!-- Top container -->
<div class="w3-bar w3-top w3-black w3-large" style="z-index:4">
<button class="w3-bar-item w3-button w3-hide-large w3-hover-none w3-hover-text-light-grey" onclick="w3_open();"><i class="fa fa-bars"></i> Menu</button>
<span class="w3-bar-item w3-right">
<c:if test="${empty sessionScope.loginUser}">
<a href="${path}/user/login">로그인</a>
<a href="${path}/user/join">회원가입</a>
</c:if>
<c:if test="${!empty sessionScope.loginUser}">
${sessionScope.loginUser.username}님이 로그인 하셨습니다.
<a href="${path}/user/logout">로그아웃</a>
</c:if>
</span>
</div>
<!-- Sidebar/menu -->
<nav class="w3-sidebar w3-collapse w3-white w3-animate-left" style="z-index:3;width:300px;" id="mySidebar"><br>
<div class="w3-container w3-row">
<div class="w3-col s4">
<img src="${path}/image/logo.png" class="w3-circle w3-margin-right" style="width:100px">
</div>
<div class="w3-col s8 w3-bar">
<c:if test="${!empty sessionScope.loginUser}">
<span>반갑습니다, <strong>${sessionScope.loginUser.username}님</strong></span><br>
</c:if>
<c:if test="${empty sessionScope.loginUser}">
<span><strong>로그인 하세요.</strong></span><br>
</c:if>
</div>
</div>
<hr>
<div class="w3-bar-block">
<a href="#" class="w3-bar-item w3-button w3-padding-16 w3-hide-large w3-dark-grey w3-hover-black" onclick="w3_close()" title="close menu"><i class="fa fa-remove fa-fw"></i> Close Menu</a>
<a href="${path}/user/mypage?id=${loginUser.userid}" class="w3-bar-item w3-button w3-padding w3-blue">
<i class="fa fa-users fa-fw">
</i> 회원관리</a>
<a href="${path}/item/list" class="w3-bar-item w3-button w3-padding">
<i class="fa fa-eye fa-fw">
</i> 상품관리</a>
<hr>
<a href="${path}/board/list?doardid=1" class="w3-bar-item w3-button w3-padding">
<i class="fa fa-users fa-fw">
</i> 공지사항</a>
<a href="${path}/board/list?boardid=2" class="w3-bar-item w3-button w3-padding">
<i class="fa fa-bullseye fa-fw">
</i> 자유게시판</a>
<a href="${path}/board/list?boardid=3" class="w3-bar-item w3-button w3-padding">
<i class="fa fa-diamond fa-fw">
</i> QnA</a>
</div>
</nav>
<!-- Overlay effect when opening sidebar on small screens -->
<div class="w3-overlay w3-hide-large w3-animate-opacity" onclick="w3_close()" style="cursor:pointer" title="close side menu" id="myOverlay"></div>
<!-- !PAGE CONTENT! -->
<div class="w3-main" style="margin-left:300px;margin-top:43px;">
<!-- Header -->
<header class="w3-container" style="padding-top:22px">
<h5><b><i class="fa fa-dashboard"></i> My Dashboard</b></h5>
</header>
<div class="w3-row-padding w3-margin-bottom">
<div class="w3-quarter">
<div class="w3-container w3-red w3-padding-16">
<div class="w3-left"><i class="fa fa-comment w3-xxxlarge"></i></div>
<div class="w3-right">
<h3>52</h3>
</div>
<div class="w3-clear"></div>
<h4>Messages</h4>
</div>
</div>
<div class="w3-quarter">
<div class="w3-container w3-blue w3-padding-16">
<div class="w3-left"><i class="fa fa-eye w3-xxxlarge"></i></div>
<div class="w3-right">
<h3>99</h3>
</div>
<div class="w3-clear"></div>
<h4>Views</h4>
</div>
</div>
<div class="w3-quarter">
<div class="w3-container w3-teal w3-padding-16">
<div class="w3-left"><i class="fa fa-share-alt w3-xxxlarge"></i></div>
<div class="w3-right">
<h3>23</h3>
</div>
<div class="w3-clear"></div>
<h4>Shares</h4>
</div>
</div>
<div class="w3-quarter">
<div class="w3-container w3-orange w3-text-white w3-padding-16">
<div class="w3-left"><i class="fa fa-users w3-xxxlarge"></i></div>
<div class="w3-right">
<h3>50</h3>
</div>
<div class="w3-clear"></div>
<h4>Users</h4>
</div>
</div>
</div>
<div class="w3-panel">
<sitemesh:write property="body"/>
</div>
<hr>
<!-- Footer -->
<footer class="w3-container w3-padding-16 w3-light-grey">
<h4>FOOTER</h4>
<p>Powered by <a href="https://www.w3schools.com/w3css/default.asp" target="_blank">w3.css</a></p>
</footer>
<!-- End page content -->
</div>
<script>
// Get the Sidebar
var mySidebar = document.getElementById("mySidebar");
// Get the DIV with overlay effect
var overlayBg = document.getElementById("myOverlay");
// Toggle between showing and hiding the sidebar, and add overlay effect
function w3_open() {
if (mySidebar.style.display === 'block') {
mySidebar.style.display = 'none';
overlayBg.style.display = "none";
} else {
mySidebar.style.display = 'block';
overlayBg.style.display = "block";
}
}
// Close the sidebar with the close button
function w3_close() {
mySidebar.style.display = "none";
overlayBg.style.display = "none";
}
</script>
</body>
</html>
📌 UserController.java 내용 추가
package controller;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import logic.ShopService;
import logic.User;
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private ShopService service;
@GetMapping("*") // * : 그 외 모든 get 방식 요청
public ModelAndView getUser() {
ModelAndView mav = new ModelAndView();
mav.addObject(new User());
return mav;
}
@PostMapping("join")
public ModelAndView join (@Valid User user, BindingResult bresult) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) { //입력값 오류 발생
mav.getModel().putAll(bresult.getModel());
//전반적인 오류코드 등록
bresult.reject("error.input.user");
return mav;
}
//db에 회원정보 등록
try {
service.userInsert(user);
mav.addObject("user", user);
//DataIntegrityViolationException : 중복키 오류
// 같은 이름의 userid 값이 존재
} catch(DataIntegrityViolationException e) {
e.printStackTrace();
bresult.reject("error.duplicate.user");
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.setViewName("redirect:login");
return mav;
}
/*
* 로그인 - POST 방식 요청
* 1. 유효성 검증
* User객체에 저장된 파라미터 값을 이용하여 유효성검증
* 2. 입력받은 userid, password로 db에서 해당 정보를 읽기.
* - userid가 없는 경우
* - password가 틀린 경우
* - 정상적인 사용자인 경우 : session에 로그인 정보 등록하기
* session.setAttribute("loginUser", user 객체)
*/
@PostMapping("login")
public ModelAndView login(@Valid User user, BindingResult bresult, HttpSession session) {
ModelAndView mav = new ModelAndView();
//1. 유효성 검증
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
bresult.reject("error.input.login");
return mav;
}
//2. 입력받은 userid, password로 db에서 해당 정보를 읽기.
try {
User dbUser = service.getUser(user.getUserid());
if(user.getPassword().equals(dbUser.getPassword())) { //정상적인 사용자 인 경우
session.setAttribute("loginUser", dbUser);
} else {
bresult.reject("error.login.password");
mav.getModel().putAll(bresult.getModel());
return mav;
}
//EmptyResultDataAccessException : 해당 레코드 없음
} catch(EmptyResultDataAccessException e) { //id가 없는 경우 예외처리
bresult.reject("error.login.id");
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.setViewName("redirect:mypage?id=" + user.getUserid());
return mav;
}
//http://localhost:8088/springmvc1/user/logout
@RequestMapping("logout") //핵심 메서드 : 기본 실행 메서드 (진짜 수행에 기본이 되는)
public String loginCheckLogout(HttpSession session) {
session.invalidate();
return "redirect:login";
}
/*
* AOP 설정하기 : UserLoginAspect 클래스의 userIdCheck 메서드로 구현하기.
* 1. pointcut : UserController 클래스의 idCheck로 시작하는 메서드이고,
* 마지막 매개변수의 id,session인 경우
* 2. 로그인 여부 검증
* - 로그인이 안된경우 로그인 후 거래하세요. 메세지 출력. login페이지 호출
* 3. admin이 아니면서, 로그인 아이디와 id값이 다른 경우
* 본인만 거래 가능합니다. 메세지 출력. item/list 페이지 호출
*/
**@RequestMapping("mypage")
public ModelAndView idCheckMypage(String id, HttpSession session) {
System.out.println("mypage 메서드 시작");
ModelAndView mav = new ModelAndView();
//회원 정보를 조회하여 user 이름으로 뷰 전달
User user = service.getUser(id);
mav.addObject("user", user);
return mav;
}**
}