목차
-
validation.properties
-
common.css
-
56라인
-
mapper.xml
-
-
member.controller => MemberAjaxController
-
static => js폴더
-
-
-
-
js=>member.register.js
-
views/member => memberRegister.jsp 내용추가
-
header.jsp 수정
-
MemberController.java 내용추가
-
WEB-INF/tile-def =>Member.xml 내용추가
-
WEB-INF/views/member=>memberLogin.jsp
-
member.css수정
-
#member_login 이라고 쓴 곳이 수정한
-
validation.propertie 내용수정
-
MemberController 추가
-
-
kr.spring.util => AuthCheckException
-
위에 컨트롤러 파일에서 try catch에서 Exception을 쓰기위해 따로 파일을 만들어줌
-
validation.properties 내용추가
-
MemberMapper
-
-
MemberserviceImpl
-
-
다시 Controller 수정
-
-
layout_mypage.jsp
-
nav_mypage.jsp
-
member =>memberView.jsp
-
tiles-def => member.xml 내용추가
-
static/css=>member.css 내용수정
-
static=> images => 카메라 이미지
-
static/css/common.css 내용추가
-
-
kr.spring.interceptor => loginCheckInterceptor
-
MemberMapper.java내용추가
-
MemberMapper.xml내용추가
-
MemberServiceImpl
validation.properties
#회원관리
Pattern.id=영문,숫자 4자~12자 입력
NotBlank.name=이름은 필수 항목
Pattern.passwd=영문,숫자 4자~12자 입력
Pattern.now_passwd=영문,숫자 4자~12자 입력
NotBlank.email=이메일은 필수 항목
Email.email=이메일 형식에 맞게 입력
NotBlank.phone=전화번호는 필수 항목
Size.zipcode=5자만 입력 가능
NotBlank.address1=주소는 필수 항목
NotBlank.address2=상세주소는 필수 항목
invalidPassword=비밀번호 불일치
common.css
56라인
.error-color{
color:#ff0000;
}

mapper.xml
<!-- 아이디 중복체크 및 로그인 처리-->
<select id="selectCheckMember" parameterType="string" resultType="memberVO" >
SELECT
mem_num,
id,
auth,
nick_name,
au_id,
passwd,
email
FROM spmember LEFT OUTER JOIN spmember_detail
USING (mem_num)
WHERE id=#{id}
</select>
member.controller => MemberAjaxController
package kr.spring.member.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.spring.member.service.MemberService;
import kr.spring.member.vo.MemberVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MemberAjaxController {
@Autowired
private MemberService memberService;
@GetMapping("/member/confirmId")
@ResponseBody
public Map<String,String> process(@RequestParam String id){
log.debug("<<아이디 중복 체크>> : "+id);
Map<String,String> mapAjax = new HashMap<String,String>();
MemberVO member = memberService.selectCheckMember(id);
if(member!=null) {
//아이디 중복
mapAjax.put("result","idDuplicated");
}else {
if(!Pattern.matches("^[A-Za-z0-9]{4,12}$", id)) {
//패턴 불일치
mapAjax.put("result","notMatchPattern");
}else {
//패턴이 일치하면서 아이디 미중복
mapAjax.put("result","idNotFound");
}
}
return mapAjax;
}
}
static => js폴더
jquery-3.7.1.min (1).js
0.08MB
js=>member.register.js
$(function(){
/*--------------------------
* 회원가입
*---------------------------*/
//아이디 중복 여부 저장 변수 : 0은 아이디 중복 또는 중복 체크 미실행,
// 1은 아이디 미중복
let checkId = 0;
//아이디 중복 체크
$('#confirmId').click(function(){
if($('#id').val().trim()==''){
$('#message_id').css('color','red').text('아이디를 입력하세요');
$('#id').val('').focus();
return;
}
$('#message_id').text(''); //메시지 초기화
//서버와 통신
$.ajax({
url:'confirmId',
type:'get',
data:{id:$('#id').val()},
dataType:'json',
success:function(param){
if(param.result == 'idNotFound'){
checkId =1;
$('#message_id').css('color','#000')
.text('등록 가능 ID');
}else if(param.result == 'idDuplicated'){
checkId = 0;
$('#message_id').css('color','red')
.text('중복된 ID');
$('#id').val('').focus();
}else if(param.result == 'notMatchPattern'){
checkId=0;
$('message_id').css('color','red')
.text('영문,숫자 4자~12자 입력');
$('#id').val('').focus();
}else{
checkId = 0;
alert('ID 중복 체크 오류');
}
},
error:function(){
checkId=0;
alert('네트워크 오류 발생');
}
});
});//end of click
//아이디 중복 안내 메시지 초기화
$('#member_register #id').keydown(function(){
checkId=0;
$('#message_id').text();
});//end of keydown
//submit 이벤트 발생시 아이디 중복 체크 여부 확인
$('#member_register').submit(function(){
if(checkId==0){
$('#message_id').css('color','red')
.text('아이디 중복 체크 필수');
if($('#id').val().trim()==''){
$('#id').val('').focus();
}
return false;
}
});//end of submit
});
views/member => memberRegister.jsp 내용추가
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/member.register.js"></script>
header.jsp 수정
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 상단 시작 -->
<h2 class="align-center">SpringPage</h2>
<div class="align-right">
<c:if test="${!empty user}">
<a href="${pageContext.request.contextPath}/member/myPage">마이페이지</a>
<a href="${pageContext.request.contextPath}/member/logout">로그아웃</a>
</c:if>
<c:if test="${empty user}">
<a href="${pageContext.request.contextPath}/member/registerUser">회원가입</a>
<a href="${pageContext.request.contextPath}/member/login">로그인</a>
</c:if>
<a href="${pageContext.request.contextPath}/main/main">홈으로</a>
</div>
<!-- 상단 끝 -->
MemberController.java 내용추가
/*===============================
* 회원로그인
===============================*/
//로그인 폼호출
@GetMapping("/member/login")
public String formLogin() {
return "memberLogin";
WEB-INF/tile-def =>Member.xml 내용추가
<definition name="memberLogin" extends="main">
<put-attribute name="title" value="회원로그인"/>
<put-attribute name="css" value="/WEB-INF/views/member/memberCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/member/memberLogin.jsp"/>
</definition>
WEB-INF/views/member=>memberLogin.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="form" uri="http://www.springframework.org/tags/form" %>
<!-- 회원로그인 시작 -->
<div class="page-main">
<h2>회원로그인</h2>
<form:form action="login" id="member_login"
modelAttribute="memberVO">
<form:errors element="div" cssClass="error-color"/>
<ul>
<li class="floating-label">
<form:input path="id" placeholder="아이디"
autocomplete="off" cssClass="form-input"/>
<form:label path="id">아이디</form:label>
<form:errors path="id" cssClass="error-color"/>
</li>
<li class="floating-label">
<form:password path="passwd" placeholder="비밀번호" cssClass="form-input"/>
<form:label path="passwd">비밀번호</form:label>
<form:errors path="passwd" cssClass="error-color"/>
</li>
<li>
<label for="auto"><input type="checkbox" name="auto" id="auto">로그인상태유지</label>
</li>
</ul>
<div>
<form:button class="login-btn">로그인</form:button>
</div>
</form:form>
<p class="align-center">
<input type="button" value="홈으로" class="default-btn"
onclick="location.href='${pageContext.request.contextPath}/main/main'">
<input type="button" value="비밀번호찾기" onclick="location.href='sendPassword'">
</p>
</div>
<!-- 회원가입 끝 -->
member.css수정
#member_login 이라고 쓴 곳이 수정한
/* 로그인
---------------------*/
#member_login{
width:320px;
margin:0 auto;
padding:0;
border:none;
}
#member_login ul{
padding:0;
}
.floating-label{/*floating label 설정*/
position:relative;
}
.floating-label > .form-input{
width:300px;
height:32px;
padding:0.55rem 0.55rem;
}
.floating-label > label{
position:absolute;
top:0;
left:0;
padding:1.05rem 0.75rem;
transition:all 0.25s;
}
.floating-label > .form-input::placeholder{
color:transparent;
}
.floating-label > .form-input:focus,
.floating-label > .form-input:not(:placeholder-shown){
padding-top:1.125rem;
padding-bottom:0.125rem;
}
.floating-label > .form-input:focus + label,
.floating-label > .form-input:not(:placeholder-shown) + label{
opacity:0.65;
transform:scale(0.85) translateY(-0.5rem) translateX(-0.5rem);
}
#member_login .login-btn{
width:320px;
}
#member_login label[for="auto"]{
width:200px;
padding:0 0 5px 0;
}
validation.propertie 내용수정
invalidIdOrPassword=아이디 또는 비밀번호 불일치

MemberController 추가
/*===============================
* 회원로그인
===============================*/
//로그인 폼호출
@GetMapping("/member/login")
public String formLogin() {
return "memberLogin";
}
//로그인 폼에서 전송된 데이터 처리
@PostMapping("/member/login")
public String submitLogin(@Valid MemberVO memberVO, BindingResult result, HttpSession session, HttpServletResponse response) {
log.debug("<<회원로그인>> : "+memberVO);
//유효성 체크 결과 오류가 있으면 폼 호출
//id와 passwd 필드만 체크
if(result.hasFieldErrors("id")|| result.hasFieldErrors("passwd")) {
return formLogin();
}
//로그인 체크(id,비밀번호 일치 여부 체크)
MemberVO member = null;
try {
member = memberService.selectCheckMember(memberVO.getId());
boolean check = false;
if(member !=null) {
//비밀번호 일치 여부 체크
check = member.ischeckedPassword(memberVO.getPasswd());
}
if(check) {//인증 성공
// ==== 자동로그인 체크 시작 ====//
// ==== 자동로그인 체크 끝 ====//
//인증 성공, 로그인 처리
session.setAttribute("user",member);
log.debug("<<인증 성공>>");
log.debug("<<id>> : "+member.getId());
log.debug("<<auth>> : "+member.getAuth());
log.debug("<<au_id>> : "+member.getAu_id());
if(member.getAuth() ==9) { //관리자
return "redirect:/main/admin";
}else {
return "redirect:/main/main";
}
}
//인증 실패
throw new AuthCheckException();
}catch(AuthCheckException e) {
//인증 실패로 로그인 폼 호출
if(member!=null && member.getAuth()==1) {//정지회원 메시지 표시
result.reject("noAuthority");
}else {
result.reject("invalidIdOrPassword");
}
log.debug("<<인증실패>>");
return formLogin();
}
}
/*===============================
* 로그아웃
===============================*/
@GetMapping("/member/logout")
public String processLogout(HttpSession session) { //로그아웃은 세션에있는 속성들을 다 지워야되기 떄문에 session이 필요
//로그아웃
session.invalidate();
// ==== 자동로그인 시작 ====//
// ==== 자동로그인 끝 ====//
return "redirect:/main/main";
}
kr.spring.util => AuthCheckException
위에 컨트롤러 파일에서 try catch에서 Exception을 쓰기위해 따로 파일을 만들어줌
package kr.spring.util;
public class AuthCheckException extends Exception {
}


validation.properties 내용추가
noAuthority=정지회원입니다.
MemberMapper
@Select("SELECT * FROM spmember JOIN spmember_detail USING(mem_num) WHERE mem_num=#{mem_num}")
public MemberVO selectMember(Long mem_num);
MemberserviceImpl
@Override
public MemberVO selectMember(Long mem_num) {
return memberMapper.selectMember(mem_num);
}
다시 Controller 수정
/*===============================
* 마이페이지
===============================*/
@GetMapping("/member/myPage")
public String process(HttpSession session, Model model) {
MemberVO user = (MemberVO)session.getAttribute("user");
//회원정보
MemberVO member = memberService.selectMember(user.getMem_num());
log.debug("<<MY페이지>> :"+member);
model.addAttribute("member",member);
return "myPage";
}
layout_mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><tiles:getAsString name="title"/></title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/common.css" type="text/css">
<tiles:insertAttribute name="css" ignore="true"/>
</head>
<body>
<div id="main">
<div id="main_header">
<tiles:insertAttribute name="header"/>
</div>
<div class="side-height">
<div id="page_nav">
<tiles:insertAttribute name="nav"/>
</div>
<div id="page_body">
<tiles:insertAttribute name="body"/>
</div>
</div>
<div id="main_footer" class="page-clear">
<tiles:insertAttribute name="footer"/>
</div>
</div>
</body>
</html>
nav_mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- mypage 메뉴 시작 -->
<div class="side-bar">
<ul>
<li>
<img src="${pageContext.request.contextPath}/member/photoView" width="200" height="200" class="my-photo">
<div class="camera" id="photo_btn">
<img src="${pageContext.request.contextPath}/images/camera.png" width="35">
</div>
</li>
<li>
<div id="photo_choice" style="display:none;">
<input type="file" id="upload" accept="image/gif,imgae/png,image/jpeg"><br>
<input type="button" value="전송" id="photo_submit">
<input type="button" value="취소" id="photo_reset">
</div>
</li>
<li>
<input type="button" class="menu-btn" value="비밀번호변경" onclick="changePassword">
</li>
<li>
<input type="button" class="menu-btn" value="회원탈퇴" onclick="delete">
</li>
</ul>
</div>
<!-- MyPage 메뉴 끝 -->
member =>memberView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 회원정보 시작 -->
<div class="page-main">
<h2>회원상세정보 <input type="button" value="회원정보수정" onclick="location.href='update'"></h2>
<ul>
<li>이름: ${member.name}</li>
<c:if test="${!empty member.nick_name}">
<li>별명 :${member.nick_name}</li>
</c:if>
<li>전화번호 :${member.phone}</li>
<li>이메일 :${member.email}</li>
<li>우편번호 :${member.zipcode}</li>
<li>주소 :${member.address1} ${member.address2}</li>
<li>가입일 :${member.reg_date}</li>
<c:if test="${!empty member.modify_date}">
<li>정보수정일 :${member.modify_date} </li>
</c:if>
</ul>
</div>
<!-- 회원정보 끝 -->
tiles-def => member.xml 내용추가
<!-- MyPage -->
<definition name="myPage" template="/WEB-INF/views/template/layout_mypage.jsp">
<put-attribute name="title" value="Mypage"/>
<put-attribute name="header" value="/WEB-INF/views/template/header.jsp"/>
<put-attribute name="nav" value="/WEB-INF/views/template/nav_mypage.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/member/memberView.jsp"/>
<put-attribute name="footer" value="/WEB-INF/views/template/footer.jsp"/>
</definition>
static/css=>member.css 내용수정
/* MY페이지
---------------------*/
.camera{
width:50px;
height:50px;
border-radius:100%;
background-color:#d3bb72;
position:relative;
top:-60px;
left:140px;
border:2px solid #fff;
cursor:pointer;
padding:13px 0 0 10px;
}
static=> images => 카메라 이미지

static/css/common.css 내용추가
/* Admin, MY페이지 공통
---------------------*/
.side-bar{
margin:10px 10px 10px 0;
padding:10px;
/*사이드바의 높이가 컨텐트의 높이와 동일하게 자동 조절*/
margin-bottom:-9999px;
padding-bottom:9999px;
background-color:#cecccc;
}
.side-bar ul{
margin:0;
padding:0;
}
.side-bar ul li{
padding:5px 10px 5px 10px;
}
.side-bar ul li ing{
margin-left:3px;
}
.side-height{
/*사이드바의 높이가 컨텐트 높이와 동일하게 자동 조절하기 위해 흘러넘친 배경색은 숨김*/
overflow:hidden;
margin-bottom:10px;
}
#page_nav{
float:left;
width:25%;
min-height:530px;
}
#page_body{
width:75%;
float:left;
}
.page-clear{
clear:both;
}
/* 공통 프로필
---------------------*/
.my-photo{
object-fit:cover;
/*정사각형이 아니라 직사각형일 경우 원 안에 보여지게 할 중심 이미지의 위치를 지정*/
object-position:top;
border-radius:50%;
}
코드를 수정하고 reload가 된 뒤 페이지를 새로고침하면 로그아웃이 되어서
로그인 때만 볼 수 있는 마이페이지 화면을 볼 수 없기 때문에 화면에 에러가난다.
또는 로그아웃 상태에서 링크창으로 mypage를 검색해서 들어가면 에러가 난다.
그러기 때문에 인터셉터(요청을 낚아챈다)를 만들어야된다.

kr.spring.interceptor => loginCheckInterceptor
package kr.spring.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class loginCheckInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("<<LoginCheckInterceptor 진입>>");
HttpSession session = request.getSession();
//로그인 여부 검사
if(session.getAttribute("user")==null) {
log.debug("<<LoginCheckInterceptor 로그아웃 상태>>");
//로그인이 되지 않은 상태
response.sendRedirect(request.getContextPath()+"/member/login");
return false; // 요청한 페이지(URL)를 호출하길 원하지 않을 경우 false
}
log.debug("<<LoginCheckInterceptor 로그인 상태>>");
return true; //true는 요청한 페이지(URL)가 호출될 때
}
}
kr.spring.config=>AppConfig 내용추가 (변수추가)
private loginCheckInterceptor loginCheck;
@Bean
public loginCheckInterceptor interceptor2() {
loginCheck = new loginCheckInterceptor();
return loginCheck;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//LoginCheckInterceptor 설정
registry.addInterceptor(loginCheck).addPathPatterns("/member/myPage")
.addPathPatterns("/member/update");
}
화면 실행 하고 로그인하면

디버그는 잘 작동하였다.

코드를 살짝수정 후 페이지 새로고침을 누르니 로그아웃이 된 것도 볼 수 있다.
화면역시 로그아웃 상태에서 마이페이지로 가려고하면 로그인창으로 이동된다.
MemberMapper.java내용추가
@Update("UPDATE spmember SET nick_name=#{nick_name} WHERE mem_num=#{mem_num}")
public void updateMember(MemberVO member);
MemberMapper.xml내용추가
<!-- 회원정보 수정 -->
<update id="updateMember_detail" parameterType="memberVO"> <!-- void기 떄문에 resultType 없음 -->
UPDATE spmember_detail
SET
name=#{name},
phone=#{phone},
email=#{email},
zipcode=#{zipcode},
address1=#{address1},
address2=#{address2},
modify_date=SYSDATE
WHERE mem_num=#{mem_num}
</update>
MemberServiceImpl
@Override
public void updateMember(MemberVO member) {
memberMapper.updateMember(member);
memberMapper.updateMember_detail(member);
}
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 93일차 ch15SpringPage(4) (0) | 2024.06.28 |
---|---|
쌍용교육 -JSP수업 92일차 ch15SpringPage(3) (1) | 2024.06.27 |
쌍용교육 -JSP수업 90일차 ch15SpringPage (0) | 2024.06.25 |
쌍용교육 -JSP수업 89일차 ch14SpringThymeleadf(2) (0) | 2024.06.25 |
쌍용교육 -JSP수업 88일차 ch14SpringThymeleadf (0) | 2024.06.24 |
validation.properties
#회원관리
Pattern.id=영문,숫자 4자~12자 입력
NotBlank.name=이름은 필수 항목
Pattern.passwd=영문,숫자 4자~12자 입력
Pattern.now_passwd=영문,숫자 4자~12자 입력
NotBlank.email=이메일은 필수 항목
Email.email=이메일 형식에 맞게 입력
NotBlank.phone=전화번호는 필수 항목
Size.zipcode=5자만 입력 가능
NotBlank.address1=주소는 필수 항목
NotBlank.address2=상세주소는 필수 항목
invalidPassword=비밀번호 불일치
common.css
56라인
.error-color{
color:#ff0000;
}

mapper.xml
<!-- 아이디 중복체크 및 로그인 처리-->
<select id="selectCheckMember" parameterType="string" resultType="memberVO" >
SELECT
mem_num,
id,
auth,
nick_name,
au_id,
passwd,
email
FROM spmember LEFT OUTER JOIN spmember_detail
USING (mem_num)
WHERE id=#{id}
</select>
member.controller => MemberAjaxController
package kr.spring.member.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.spring.member.service.MemberService;
import kr.spring.member.vo.MemberVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MemberAjaxController {
@Autowired
private MemberService memberService;
@GetMapping("/member/confirmId")
@ResponseBody
public Map<String,String> process(@RequestParam String id){
log.debug("<<아이디 중복 체크>> : "+id);
Map<String,String> mapAjax = new HashMap<String,String>();
MemberVO member = memberService.selectCheckMember(id);
if(member!=null) {
//아이디 중복
mapAjax.put("result","idDuplicated");
}else {
if(!Pattern.matches("^[A-Za-z0-9]{4,12}$", id)) {
//패턴 불일치
mapAjax.put("result","notMatchPattern");
}else {
//패턴이 일치하면서 아이디 미중복
mapAjax.put("result","idNotFound");
}
}
return mapAjax;
}
}
static => js폴더
jquery-3.7.1.min (1).js
0.08MB
js=>member.register.js
$(function(){
/*--------------------------
* 회원가입
*---------------------------*/
//아이디 중복 여부 저장 변수 : 0은 아이디 중복 또는 중복 체크 미실행,
// 1은 아이디 미중복
let checkId = 0;
//아이디 중복 체크
$('#confirmId').click(function(){
if($('#id').val().trim()==''){
$('#message_id').css('color','red').text('아이디를 입력하세요');
$('#id').val('').focus();
return;
}
$('#message_id').text(''); //메시지 초기화
//서버와 통신
$.ajax({
url:'confirmId',
type:'get',
data:{id:$('#id').val()},
dataType:'json',
success:function(param){
if(param.result == 'idNotFound'){
checkId =1;
$('#message_id').css('color','#000')
.text('등록 가능 ID');
}else if(param.result == 'idDuplicated'){
checkId = 0;
$('#message_id').css('color','red')
.text('중복된 ID');
$('#id').val('').focus();
}else if(param.result == 'notMatchPattern'){
checkId=0;
$('message_id').css('color','red')
.text('영문,숫자 4자~12자 입력');
$('#id').val('').focus();
}else{
checkId = 0;
alert('ID 중복 체크 오류');
}
},
error:function(){
checkId=0;
alert('네트워크 오류 발생');
}
});
});//end of click
//아이디 중복 안내 메시지 초기화
$('#member_register #id').keydown(function(){
checkId=0;
$('#message_id').text();
});//end of keydown
//submit 이벤트 발생시 아이디 중복 체크 여부 확인
$('#member_register').submit(function(){
if(checkId==0){
$('#message_id').css('color','red')
.text('아이디 중복 체크 필수');
if($('#id').val().trim()==''){
$('#id').val('').focus();
}
return false;
}
});//end of submit
});
views/member => memberRegister.jsp 내용추가
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/member.register.js"></script>
header.jsp 수정
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 상단 시작 -->
<h2 class="align-center">SpringPage</h2>
<div class="align-right">
<c:if test="${!empty user}">
<a href="${pageContext.request.contextPath}/member/myPage">마이페이지</a>
<a href="${pageContext.request.contextPath}/member/logout">로그아웃</a>
</c:if>
<c:if test="${empty user}">
<a href="${pageContext.request.contextPath}/member/registerUser">회원가입</a>
<a href="${pageContext.request.contextPath}/member/login">로그인</a>
</c:if>
<a href="${pageContext.request.contextPath}/main/main">홈으로</a>
</div>
<!-- 상단 끝 -->
MemberController.java 내용추가
/*===============================
* 회원로그인
===============================*/
//로그인 폼호출
@GetMapping("/member/login")
public String formLogin() {
return "memberLogin";
WEB-INF/tile-def =>Member.xml 내용추가
<definition name="memberLogin" extends="main">
<put-attribute name="title" value="회원로그인"/>
<put-attribute name="css" value="/WEB-INF/views/member/memberCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/member/memberLogin.jsp"/>
</definition>
WEB-INF/views/member=>memberLogin.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="form" uri="http://www.springframework.org/tags/form" %>
<!-- 회원로그인 시작 -->
<div class="page-main">
<h2>회원로그인</h2>
<form:form action="login" id="member_login"
modelAttribute="memberVO">
<form:errors element="div" cssClass="error-color"/>
<ul>
<li class="floating-label">
<form:input path="id" placeholder="아이디"
autocomplete="off" cssClass="form-input"/>
<form:label path="id">아이디</form:label>
<form:errors path="id" cssClass="error-color"/>
</li>
<li class="floating-label">
<form:password path="passwd" placeholder="비밀번호" cssClass="form-input"/>
<form:label path="passwd">비밀번호</form:label>
<form:errors path="passwd" cssClass="error-color"/>
</li>
<li>
<label for="auto"><input type="checkbox" name="auto" id="auto">로그인상태유지</label>
</li>
</ul>
<div>
<form:button class="login-btn">로그인</form:button>
</div>
</form:form>
<p class="align-center">
<input type="button" value="홈으로" class="default-btn"
onclick="location.href='${pageContext.request.contextPath}/main/main'">
<input type="button" value="비밀번호찾기" onclick="location.href='sendPassword'">
</p>
</div>
<!-- 회원가입 끝 -->
member.css수정
#member_login 이라고 쓴 곳이 수정한
/* 로그인
---------------------*/
#member_login{
width:320px;
margin:0 auto;
padding:0;
border:none;
}
#member_login ul{
padding:0;
}
.floating-label{/*floating label 설정*/
position:relative;
}
.floating-label > .form-input{
width:300px;
height:32px;
padding:0.55rem 0.55rem;
}
.floating-label > label{
position:absolute;
top:0;
left:0;
padding:1.05rem 0.75rem;
transition:all 0.25s;
}
.floating-label > .form-input::placeholder{
color:transparent;
}
.floating-label > .form-input:focus,
.floating-label > .form-input:not(:placeholder-shown){
padding-top:1.125rem;
padding-bottom:0.125rem;
}
.floating-label > .form-input:focus + label,
.floating-label > .form-input:not(:placeholder-shown) + label{
opacity:0.65;
transform:scale(0.85) translateY(-0.5rem) translateX(-0.5rem);
}
#member_login .login-btn{
width:320px;
}
#member_login label[for="auto"]{
width:200px;
padding:0 0 5px 0;
}
validation.propertie 내용수정
invalidIdOrPassword=아이디 또는 비밀번호 불일치

MemberController 추가
/*===============================
* 회원로그인
===============================*/
//로그인 폼호출
@GetMapping("/member/login")
public String formLogin() {
return "memberLogin";
}
//로그인 폼에서 전송된 데이터 처리
@PostMapping("/member/login")
public String submitLogin(@Valid MemberVO memberVO, BindingResult result, HttpSession session, HttpServletResponse response) {
log.debug("<<회원로그인>> : "+memberVO);
//유효성 체크 결과 오류가 있으면 폼 호출
//id와 passwd 필드만 체크
if(result.hasFieldErrors("id")|| result.hasFieldErrors("passwd")) {
return formLogin();
}
//로그인 체크(id,비밀번호 일치 여부 체크)
MemberVO member = null;
try {
member = memberService.selectCheckMember(memberVO.getId());
boolean check = false;
if(member !=null) {
//비밀번호 일치 여부 체크
check = member.ischeckedPassword(memberVO.getPasswd());
}
if(check) {//인증 성공
// ==== 자동로그인 체크 시작 ====//
// ==== 자동로그인 체크 끝 ====//
//인증 성공, 로그인 처리
session.setAttribute("user",member);
log.debug("<<인증 성공>>");
log.debug("<<id>> : "+member.getId());
log.debug("<<auth>> : "+member.getAuth());
log.debug("<<au_id>> : "+member.getAu_id());
if(member.getAuth() ==9) { //관리자
return "redirect:/main/admin";
}else {
return "redirect:/main/main";
}
}
//인증 실패
throw new AuthCheckException();
}catch(AuthCheckException e) {
//인증 실패로 로그인 폼 호출
if(member!=null && member.getAuth()==1) {//정지회원 메시지 표시
result.reject("noAuthority");
}else {
result.reject("invalidIdOrPassword");
}
log.debug("<<인증실패>>");
return formLogin();
}
}
/*===============================
* 로그아웃
===============================*/
@GetMapping("/member/logout")
public String processLogout(HttpSession session) { //로그아웃은 세션에있는 속성들을 다 지워야되기 떄문에 session이 필요
//로그아웃
session.invalidate();
// ==== 자동로그인 시작 ====//
// ==== 자동로그인 끝 ====//
return "redirect:/main/main";
}
kr.spring.util => AuthCheckException
위에 컨트롤러 파일에서 try catch에서 Exception을 쓰기위해 따로 파일을 만들어줌
package kr.spring.util;
public class AuthCheckException extends Exception {
}


validation.properties 내용추가
noAuthority=정지회원입니다.
MemberMapper
@Select("SELECT * FROM spmember JOIN spmember_detail USING(mem_num) WHERE mem_num=#{mem_num}")
public MemberVO selectMember(Long mem_num);
MemberserviceImpl
@Override
public MemberVO selectMember(Long mem_num) {
return memberMapper.selectMember(mem_num);
}
다시 Controller 수정
/*===============================
* 마이페이지
===============================*/
@GetMapping("/member/myPage")
public String process(HttpSession session, Model model) {
MemberVO user = (MemberVO)session.getAttribute("user");
//회원정보
MemberVO member = memberService.selectMember(user.getMem_num());
log.debug("<<MY페이지>> :"+member);
model.addAttribute("member",member);
return "myPage";
}
layout_mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><tiles:getAsString name="title"/></title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/common.css" type="text/css">
<tiles:insertAttribute name="css" ignore="true"/>
</head>
<body>
<div id="main">
<div id="main_header">
<tiles:insertAttribute name="header"/>
</div>
<div class="side-height">
<div id="page_nav">
<tiles:insertAttribute name="nav"/>
</div>
<div id="page_body">
<tiles:insertAttribute name="body"/>
</div>
</div>
<div id="main_footer" class="page-clear">
<tiles:insertAttribute name="footer"/>
</div>
</div>
</body>
</html>
nav_mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- mypage 메뉴 시작 -->
<div class="side-bar">
<ul>
<li>
<img src="${pageContext.request.contextPath}/member/photoView" width="200" height="200" class="my-photo">
<div class="camera" id="photo_btn">
<img src="${pageContext.request.contextPath}/images/camera.png" width="35">
</div>
</li>
<li>
<div id="photo_choice" style="display:none;">
<input type="file" id="upload" accept="image/gif,imgae/png,image/jpeg"><br>
<input type="button" value="전송" id="photo_submit">
<input type="button" value="취소" id="photo_reset">
</div>
</li>
<li>
<input type="button" class="menu-btn" value="비밀번호변경" onclick="changePassword">
</li>
<li>
<input type="button" class="menu-btn" value="회원탈퇴" onclick="delete">
</li>
</ul>
</div>
<!-- MyPage 메뉴 끝 -->
member =>memberView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 회원정보 시작 -->
<div class="page-main">
<h2>회원상세정보 <input type="button" value="회원정보수정" onclick="location.href='update'"></h2>
<ul>
<li>이름: ${member.name}</li>
<c:if test="${!empty member.nick_name}">
<li>별명 :${member.nick_name}</li>
</c:if>
<li>전화번호 :${member.phone}</li>
<li>이메일 :${member.email}</li>
<li>우편번호 :${member.zipcode}</li>
<li>주소 :${member.address1} ${member.address2}</li>
<li>가입일 :${member.reg_date}</li>
<c:if test="${!empty member.modify_date}">
<li>정보수정일 :${member.modify_date} </li>
</c:if>
</ul>
</div>
<!-- 회원정보 끝 -->
tiles-def => member.xml 내용추가
<!-- MyPage -->
<definition name="myPage" template="/WEB-INF/views/template/layout_mypage.jsp">
<put-attribute name="title" value="Mypage"/>
<put-attribute name="header" value="/WEB-INF/views/template/header.jsp"/>
<put-attribute name="nav" value="/WEB-INF/views/template/nav_mypage.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/member/memberView.jsp"/>
<put-attribute name="footer" value="/WEB-INF/views/template/footer.jsp"/>
</definition>
static/css=>member.css 내용수정
/* MY페이지
---------------------*/
.camera{
width:50px;
height:50px;
border-radius:100%;
background-color:#d3bb72;
position:relative;
top:-60px;
left:140px;
border:2px solid #fff;
cursor:pointer;
padding:13px 0 0 10px;
}
static=> images => 카메라 이미지

static/css/common.css 내용추가
/* Admin, MY페이지 공통
---------------------*/
.side-bar{
margin:10px 10px 10px 0;
padding:10px;
/*사이드바의 높이가 컨텐트의 높이와 동일하게 자동 조절*/
margin-bottom:-9999px;
padding-bottom:9999px;
background-color:#cecccc;
}
.side-bar ul{
margin:0;
padding:0;
}
.side-bar ul li{
padding:5px 10px 5px 10px;
}
.side-bar ul li ing{
margin-left:3px;
}
.side-height{
/*사이드바의 높이가 컨텐트 높이와 동일하게 자동 조절하기 위해 흘러넘친 배경색은 숨김*/
overflow:hidden;
margin-bottom:10px;
}
#page_nav{
float:left;
width:25%;
min-height:530px;
}
#page_body{
width:75%;
float:left;
}
.page-clear{
clear:both;
}
/* 공통 프로필
---------------------*/
.my-photo{
object-fit:cover;
/*정사각형이 아니라 직사각형일 경우 원 안에 보여지게 할 중심 이미지의 위치를 지정*/
object-position:top;
border-radius:50%;
}
코드를 수정하고 reload가 된 뒤 페이지를 새로고침하면 로그아웃이 되어서
로그인 때만 볼 수 있는 마이페이지 화면을 볼 수 없기 때문에 화면에 에러가난다.
또는 로그아웃 상태에서 링크창으로 mypage를 검색해서 들어가면 에러가 난다.
그러기 때문에 인터셉터(요청을 낚아챈다)를 만들어야된다.

kr.spring.interceptor => loginCheckInterceptor
package kr.spring.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class loginCheckInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("<<LoginCheckInterceptor 진입>>");
HttpSession session = request.getSession();
//로그인 여부 검사
if(session.getAttribute("user")==null) {
log.debug("<<LoginCheckInterceptor 로그아웃 상태>>");
//로그인이 되지 않은 상태
response.sendRedirect(request.getContextPath()+"/member/login");
return false; // 요청한 페이지(URL)를 호출하길 원하지 않을 경우 false
}
log.debug("<<LoginCheckInterceptor 로그인 상태>>");
return true; //true는 요청한 페이지(URL)가 호출될 때
}
}
kr.spring.config=>AppConfig 내용추가 (변수추가)
private loginCheckInterceptor loginCheck;
@Bean
public loginCheckInterceptor interceptor2() {
loginCheck = new loginCheckInterceptor();
return loginCheck;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//LoginCheckInterceptor 설정
registry.addInterceptor(loginCheck).addPathPatterns("/member/myPage")
.addPathPatterns("/member/update");
}
화면 실행 하고 로그인하면

디버그는 잘 작동하였다.

코드를 살짝수정 후 페이지 새로고침을 누르니 로그아웃이 된 것도 볼 수 있다.
화면역시 로그아웃 상태에서 마이페이지로 가려고하면 로그인창으로 이동된다.
MemberMapper.java내용추가
@Update("UPDATE spmember SET nick_name=#{nick_name} WHERE mem_num=#{mem_num}")
public void updateMember(MemberVO member);
MemberMapper.xml내용추가
<!-- 회원정보 수정 -->
<update id="updateMember_detail" parameterType="memberVO"> <!-- void기 떄문에 resultType 없음 -->
UPDATE spmember_detail
SET
name=#{name},
phone=#{phone},
email=#{email},
zipcode=#{zipcode},
address1=#{address1},
address2=#{address2},
modify_date=SYSDATE
WHERE mem_num=#{mem_num}
</update>
MemberServiceImpl
@Override
public void updateMember(MemberVO member) {
memberMapper.updateMember(member);
memberMapper.updateMember_detail(member);
}
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 93일차 ch15SpringPage(4) (0) | 2024.06.28 |
---|---|
쌍용교육 -JSP수업 92일차 ch15SpringPage(3) (1) | 2024.06.27 |
쌍용교육 -JSP수업 90일차 ch15SpringPage (0) | 2024.06.25 |
쌍용교육 -JSP수업 89일차 ch14SpringThymeleadf(2) (0) | 2024.06.25 |
쌍용교육 -JSP수업 88일차 ch14SpringThymeleadf (0) | 2024.06.24 |