<복습>
********
(주의)폼에서 파일 업로드 파라미터네임은 반드시 upload로 지정해야 함
MultipartFile -> byte[]
********
dao쪽 mapper는 @Mapper가 있어야함
회원가입 폼에 우편번호 검색 api + 버튼 넣기 (아래 api 소스코드는 생략)
views
member
memberRegister.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!-- 내용 시작 -->
<div class="page-main">
<h2>회원가입</h2>
<form:form action="registerUser" id="member_register" modelAttribute="memberVO">
<form:errors element="div" cssClass="error-color"/>
<ul>
<li>
<form:label path="id">아이디</form:label>
<form:input path="id" placeholder="영문,숫자만 4~12자" autocomplete="off"/>
<input type="button" id="confirmId" value="ID중복체크" class="default-btn">
<span id="message_id"></span>
<form:errors path="id" cssClass="error-color"/>
</li>
<li>
<form:label path="name">이름</form:label>
<form:input path="name"/>
<form:errors path="name" cssClass="error-color"/>
</li>
<li>
<form:label path="nick_name">별명</form:label>
<form:input path="nick_name"/>
</li>
<li>
<form:label path="passwd">비밀번호</form:label>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error-color"/>
</li>
<li>
<form:label path="phone">전화번호</form:label>
<form:input path="phone"/>
<form:errors path="phone" cssClass="error-color"/>
</li>
<li>
<form:label path="email">이메일</form:label>
<form:input path="email" placeholder="영문,숫자만 4~12자"/>
<form:errors path="email" cssClass="error-color"/>
</li>
<li>
<form:label path="zipcode">우편번호</form:label>
<form:input path="zipcode"/>
<input type="button" onclick="execDaumPostcode()" value="우편번호 찾기" class="default-btn">
<form:errors path="zipcode" cssClass="error-color"/>
</li>
<li>
<form:label path="address1">주소</form:label>
<form:input path="address1"/>
<form:errors path="address1" cssClass="error-color"/>
</li>
<li>
<form:label path="address2">상세주소</form:label>
<form:input path="address2"/>
<form:errors path="address2" cssClass="error-color"/>
</li>
</ul>
<div class="align-center">
<form:button class="default-btn">전송</form:button>
<input type="button" value="홈으로" class="default-btn" onclick="location.href='${pageContext.request.contextPath}/main/main'">
</div>
</form:form>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/member.register.js"></script>
button onclick="api메서드명" 넣으면 됨
<회원가입 처리>
회원가입 - sql문 명시 (짧은 sql문)
kr.spring.member.dao
MemberMapper.java
package kr.spring.member.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import kr.spring.member.vo.MemberVO;
@Mapper
public interface MemberMapper {
//회원관리 - 사용자
@Select("SELECT spmember_seq.nextval FROM dual")
public int selectMem_num(); //pk 구하기
@Insert("INSERT INTO spmember (mem_num,id,nick_name) VALUES (#{mem_num},#{id},#{nick_name})")
public void insertMember(MemberVO member);
public void insertMember_detail(MemberVO member);
public MemberVO selectCheckMember(String id);
public MemberVO selectMember(int mem_num);//한건의 레코드 반환
public void updateMember(MemberVO member);
public void updateMember_detail(MemberVO member);
public void updatePassword(MemberVO member);
public void deleteMember(int mem_num);
public void deleteMember_detail(int mem_num);
//회원관리 - 관리자
}
selectMem_num 하나의 메서드 가져오기
insertMember insert등록
이 두가지는 sql문이 짧기 때문에 dao interface에 어노테이션을 이용해서 바로 명시
tiles는 #{} 를 쓰기 때문에 꼭 #{}로 명시
회원가입 - sql문 명시 (긴 sql문)
kr.spring.member.dao
MemberMapper.xml
<?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="kr.spring.member.dao.MemberMapper">
<!-- 회원가입 상세 -->
<insert id="insertMember_detail" parameterType="memberVO">
INSERT INTO spmember_detail (
mem_num,
name,
passwd,
phone,
email,
zipcode,
address1,
address2)
VALUES (
#{mem_num},
#{name},
#{passwd},
#{phone},
#{email},
#{zipcode},
#{address1},
#{address2})
</insert>
</mapper>
<insert id="insertMember_detail" parameterType="memberVO">
alias 가 있어서 MemberVO > memberVO
Service파일에서 묶어서 처리
kr.spring.member.service
MemberServiceImpl
package kr.spring.member.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import kr.spring.member.dao.MemberMapper;
import kr.spring.member.vo.MemberVO;
@Service
@Transactional
public class MemberServiceImpl implements MemberService{
@Autowired
private MemberMapper memberMapper;
@Override
public void insertMember(MemberVO member) {
//member insert 관련 메서드들을 트랜잭션 단위로 묶어서 처리
member.setMem_num(memberMapper.selectMem_num());
memberMapper.insertMember(member);
memberMapper.insertMember_detail(member);
}
관련 메서드들을 묶어서 하나의 메서드(?)로 처리함
컨트롤러에서 호출
kr.spring.member.controller
MemberController
//회원가입 폼 호출
@GetMapping("/member/registerUser")
public String form() {
return "memberRegister"; //tiles설정명 (/등의 경로가 없기 때문에 jsp가 아니라는 걸 알 수 있음)
}
//전송된 회원 데이터 처리
@PostMapping("/member/registerUser")
public String submit(@Valid MemberVO memberVO, BindingResult result,
Model model, HttpServletRequest request) {
log.debug("<<회원가입>> : " + memberVO);
//유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasErrors()) {
return form();
}
//회원가입
memberService.insertMember(memberVO);
model.addAttribute("accessTitle", "회원가입");
model.addAttribute("accessMsg", "회원가입이 완료되었습니다.");
model.addAttribute("accessUrl", request.getContextPath()+"/main/main");
return "common/resultView"; //경로/jsp
}
<화면 출력 방법>
1. tiles를 사용, 레이아웃- include 형태로 호출하는 경우
2. jsp 단독으로 호출하는 경우
return시 경로가 있다면 2번 방법을 사용한 것임 (jsp경로)
데이터 세팅하는 인자 2개 추가됨
Model model = request에 저장해서 정보를 바로 받을 수 있게 인자로 추가함
HttpServletRequest request =
+
HttpServletRequest를 사용하면, 값을 받아올 수가 있는데
만약 회원 정보를 컨트롤러로 보냈을 때 HttpServletRequest 객체 안에 모든 데이터들이 들어가게 됩니다!
참고 주소
https://chobopark.tistory.com/43
HttpServletRequest 개념 및 사용법
안녕하세요. 오늘은 HttpServletRequest 에 대해 이야기해보겠습니다. JSP 기본 내장 객체 중 request 객체는 JSP에서 가장 많이 사용되는 객체입니다. 웹브라우저 사용자인 클라이언트로부터 서버로 요
chobopark.tistory.com
회원가입 완료 시 폼 생성
views
common (folder)
resultView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${accessTitle}</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-one">
<h2>${accessTitle}</h2>
<div class="result-display">
<div class="align-center">
${accessMsg}
<p> <%-- p 하나만 넣으면 두줄 엔터 효과 --%>
<input type="button" value="이동" onclick="location.href='${accessUrl}'">
</div>
</div>
</div>
</body>
</html>
회원가입 시 유효성 검사
src/main/resources
messages (package)
validation.properties (file)
초기 설정파일인 application.yml 에서
messages: #메시지
basename: messages.validation
encoding: UTF-8
라고 기재했기 때문에 유효성 메시지는
messages 폴더 아래 validation 프로퍼티즈 파일로 사용해야함
#회원관리
Pattern.id=영문,숫자 4자이상 12자이하 입력
NotBlank.name=이름은 필수
Pattern.passwd=영문,숫자 4자이상 12자이하 입력
Pattern.now_passwd=영문,숫자 4자이상 12자이하 입력
NotBlank.phone=전화번호는 필수
NotBlank.email=이메일은 필수
Email.email=이메일 형식에 맞게 입력해야 함
Size.zipcode=5자만 입력 가능
NotBlank.address1=주소는 필수
NotEmpty.address2=상세주소는 필수
restart 후 웹 브라우저 열고 회원가입하면 유효성 검사 포함 정상작동됨 (oracle 에도 저장됨)
<아이디 중복체크-ajax 통신>
MemberMapper의 selectCheckMember 메서드가 null 이면 비중복 / null이 아니면 중복으로 체크
MemberMapper.xml
<!-- 아이디 중복 체크 및 로그인 체크 -->
<select id="selectCheckMember" parameterType="string">
SELECT
id,
auth,
nick_name,
au_id,
passwd,
email
FROM spmember LEFT OUTER JOIN spmember_detail
USING(mem_num)
WHERE id=#{id}
</select>
서비스 파일에 기재
ServiceImpl
@Override
public MemberVO selectCheckMember(String id) {
return memberMapper.selectCheckMember(id);
}
ajax 통신은 controller 따로 생성
src/main/java
kr.spring.member.controller
MemberAjaxController (class)
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.RequestMapping;
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;
@RequestMapping("/member/confirmId")
@ResponseBody //ajax를 자동으로 만들어줌
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;
}
}
**이클립스에서 다시 내용 복사하기 (정확하지 않을 수 있음)
js로 패턴검사를 할 수도 있고 해당 컨트롤러 클래스에서도 할 수 있음
if(!Pattern.matches("정규표현식", 매핑할값)
=============================
저장 후 웹 페이지에서
http://localhost:8000/member/confirmId?id=dragon 이런식으로 test해보기
[정상출력화면]
{"result":"idDuplicated"}
jquery 사용하여 ajax 통신
src/main/resources
static
js (folder)
jquery 3.6.0.min.js 붙여넣기
memberRegister.jsp에서 jquery 링크 추가
memberRegister.jsp
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/member.register.js"></script>
static
js
member.register.js (javascript file)
**
mave 검색할거냐고 물어보면 그냥 cancel누르면 됨
open with > generic text editor
$(function(){
/*-------------------
* 회원가입
*--------------------*/
//아이디 중복 여부 저장 변수 : 0은 아이디 중복 또는 중복 체크 미실행, 1은 아이디 미중복
let checkId = 0;
//아이디 중복 체크
$('#confirmId').click(function(){
if($('#id').val().trim()==''){
$('#message_id').css('color','red').text('아이디를 입력하세요');
$('#id').val('').focus();
return; //submit이 아닌 경우 return (false x)
}
//서버와 통신
$.ajax({
url:'confirmId',
type:'post',
data:{id:$('#id').val()},
dataType:'json',
success:function(param){
if(param.result == 'idNotFound'){
$('#message_id').css('color','#000').text('등록 가능 ID');
checkId = 1;
}else if(param.result == 'idDuplicated'){
$('#message_id').css('color','red').text('중복된 ID');
$('#id').val('').focus();
checkId = 0;
}else if(param.result == 'notMatchPattern'){
$('#message_id').css('color','red').text('영문,숫자만 4~12자 입력');
$('#id').val('').focus();
checkId = 0;
}else {
checkId = 0;
alert('ID 중복 체크 오류');
}
},
error:function(){
checkId=0;
alert('네트워크 오류 발생');
}
}); //end of ajax
}); //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
});
이제 실행 후 회원가입 메뉴-ID중복체크 누르면 유효성 체크 됨
<로그인 처리>
MemberController
/*=======================
* 회원 로그인
*======================= */
//로그인 폼 호출
@GetMapping("/member/login")
public String formLogin() {
return "memberLogin"; //tiles(경로정보X)
}
selectCheckMember 값을 가져와서 로그인
<로그인 시 tiles 화면>
controller에서 tiles로 return 시켰기 때문에 화면 레이아웃을 매핑해서 출력해야함
member.xml
<definition name="memberLogin" extends="main">
<put-attribute name="title" value="회원로그인"/>
<put-attribute name="body" value="/WEB-INF/views/member/memberLogin.jsp"/>
</definition>
뷰 만들기
views
member
memberLogin.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!-- 내용 시작 -->
<div class="page-main">
<h2>회원로그인</h2>
<form:form id="member_login" action="login" modelAttribute="memberVO">
<form:errors element="div" cssClass="error-color"/>
<ul>
<li class="floating-label">
<form:input path="id" placeholder="아이디" cssClass="form-input"
autocomplete="off"/>
<form:label path="id">아이디</form:label>
<form:errors path="id" element="div" 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" element="div" 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="홈으로" onclick="location.href='${pageContext.request.contextPath}/main/main'">
</p>
</div>
<!-- 내용 끝 -->
로그인 처리
MemberController
//전송된 데이터 처리
@PostMapping("/member/login")
public String submitLogin(@Valid MemberVO memberVO,BindingResult result,HttpSession session,
Model model,HttpServletResponse response) {
log.debug("<<회원로그인>> : " + memberVO);
//유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasFieldErrors("id") || result.hasFieldErrors("passwd")) {
return formLogin();
}
return "";
}
자동로그인 시 필요함 >> HttpServletResponse response
아이디와 비밀번호 에러가 있을 경우 폼 재호출 후 에러 메시지 화면 출력
DB 자료와 비교하여 로그인 처리 위해 예외 클래스 생성
src/main/java
kr.spring.util (package)
AuthCheckException (class)
package kr.spring.util;
//사용자 정의 예외클래스
public class AuthCheckException extends Exception{
}
AuthCheckException 라는 예외 타입만 사용할 거기 때문에 내용 명시 안했음 (로그인 체크)
컨트롤러에서 확인
MemberController
//전송된 데이터 처리
@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()); //id를 읽어와서 해당 아이디랑 매핑되는 정보가 있는지 없는지 체크
boolean check = false;
//id를 넣어서 membervo가 있다 -> 비밀번호 체크
if(member!=null) {
//비밀번호 일치 여부 체크
check = member.isCheckedPassword(memberVO.getPasswd());
}
if(check) {//인증 성공시
//=====자동 로그인 체크 시작=====//
//=====자동 로그인 체크 끝=====//
//인증 성공, 로그인 처리
session.setAttribute("user", member); //user란 이름으로 통째로 객체 넣기 (저장할 데이터 多 경우)
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) {
log.debug("<<인증 실패>>");
//인증 실패로 로그인 폼 호출
if(member!=null && member.getAuth()==1) { //정지회원
result.reject("noAuthority");
}else {
result.reject("invalidIdOrPassword");
}
return formLogin();
}
}
유효성 검사 메시지
messages
validation.properties
noAuthority=정지회원입니다.
invalidIdOrPassword=아이디 또는 비밀번호 불일치
실행 후 공란 로그인 > 유효성 체크
잘못 기입 시 > 유효성 체크
정상 기입 시 > main 페이지
<로그아웃>
MemberController
/*=======================
* 회원 로그아웃
*======================= */
@RequestMapping("/member/logout")
public String processLogout(HttpSession session,HttpServletResponse response) {
//로그아웃
session.invalidate();
//======= 자동로그인 처리 시작(쿠키 삭제) =========//
//======= 자동로그인 처리 끝(쿠키 삭제) =========//
return "redirect:/main/main";
}
로그인 후 로그아웃 누르면 로그아웃됨
<마이페이지> tiles nav
views
template
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,image/png,image/jpeg">
<input type="button" value="전송" id="photo_submit">
<input type="button" value="취소" id="photo_reset">
</div>
</li>
</ul>
<ul>
<li>
<input type="button" class="menu-btn" value="비밀번호변경" onclick="location.href='${pageContext.request.contextPath}/member/changePassword'">
</li>
<li>
<input type="button" class="menu-btn" value="채팅" onclick="location.href='${pageContext.request.contextPath}/talk/talkList'">
</li>
<li>
<input type="button" class="menu-btn" value="회원탈퇴" onclick="location.href='${pageContext.request.contextPath}/member/delete'">
</li>
</ul>
</div>
<!-- MyPage 메뉴 끝 -->
<마이페이지> layout 페이지
views
template
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/layout.css">
</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="main_body">
<tiles:insertAttribute name="body"/>
</div>
</div>
<div id="main_footer" class="page_clear">
<tiles:insertAttribute name="footer"/>
</div>
</div>
</body>
</html>
<마이페이지> tiles body
views
member
memberView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h1>MyPage</h1>
컨트롤러 호출
MemberController
/*=======================
* MyPage
*======================= */
@RequestMapping("/member/myPage")
public String process() {
return "myPage";
}
설정파일 mapping
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>
로그인 후 my페이지 정상 출력
'학원 > spring' 카테고리의 다른 글
1.16 (tiles-게시판 기본폼 호출, 글등록, 목록처리(+검색)) (0) | 2024.01.17 |
---|---|
1.15 (spring tiles (db연동)- 회원관리 끝 / 게시판 시작) (0) | 2024.01.15 |
1.10 (Tiles-Lombok install,기본설정,페이지 만들기) (0) | 2024.01.11 |
1.10 (myBatis(boot)-crud/spring-tiles crud) (0) | 2024.01.11 |
1.9 (myBatis-목록,상세,수정,삭제/ myBatis(boot) 설정,대문페이지) (0) | 2024.01.09 |