본문 바로가기
멀티캠퍼스 풀스택 과정/백엔드

Spring:6 로그인 회원가입폼 구현 하고 회원가입 DB연결 -3

by 이쟝 2022. 3. 17.

 

Spring:4 spring(maven project)를 Mybatis, Mysql과 연결하기(환경설정)-1

Spring:5 spring(maven project)기본 스타일 지정하기-2

1. DB 설계 (모델링으로 Member table 생성)

Database > Forward Engineer > member table 생성하기
id, pwd, name, tel, email, writedate(writedate는 현재 날짜로 자동 생성된다.)
주의할 점! root-context에서 연결한 database에 table을 만들어야 한다. 

 

2. views(홈)에 로그인 메뉴를 눌렀을 때 보일 로그인 폼 만들기

1. views밑에 member 폴더 생성 > signIn.jsp 파일 생성

- container 부분에 들어가기 때문에 html 코드 불필요
- 아직 db와 연결을 안 했기 때문에 action이 실행되지 않는다.(loginOk 아직 실행 안됨)
- db의 컬럼명과 동일해야 함(아이디는 userid, 비밀번호는 userpwd)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<link rel="stylesheet" href="/myappy/css/signInStyle.css" type="text/css"/>
<script src="/myappy/js/signInJs.js"></script>
<div class="container">
	<div id="login">
		<h1>로그인</h1>
		<hr/>
		<form method="post" action="/myappy/member/loginOk" id="loginFrm" onsubmit="return LoginFrmCheck()">
			<ul>
				<li>아이디</li>
				<li><input type="text" name="userid" id="userid"/></li>
				<li>비밀번호</li>
				<li><input type="password" name="userpwd" id="userpwd"/></li>
				<li><input type="button" value="로그인" onclick="LoginFrmCheck()"/>
					<input type="reset" value="취소"/></li>
			</ul>
		</form>
	</div>
</div>
더보기

signInStyle.css

@charset "UTF-8";
#login{
	width:300px;
	margin:0 auto;
}
#login h1{
	text-align:center;
}
#loginFrm>ul>li{
	float:left;
	width:30%;
}
#loginFrm>ul>li:nth-child(2n){
	width:70%;
}
#loginFrm>ul>li:last-of-type{
	width:100%;
	text-align:center;
	margin-top:30px;
}

signInJs.js

function LoginFrmCheck(){
	let id = document.querySelector("#userid");
	if(id.value=="") {  // 아이디가 없을 때
		alert("아이디를 입력하세요");
		id.focus(); // 커서를 해당객체에 위치시킨다.
		return false;  // return 만나면 함수실행 끝!
	}
	if(document.querySelector("#userpwd").value=="") {
		alert("비밀번호을 입력하세요");
		document.querySelector("#userpwd").focus();
		return false;
	}
	
	// 아이디와 비밀번호가 모두 입력되었을 때 submit발생
	// js로 form태그의 submit 발생(button태그이기 때문에)
	document.getElementById("loginFrm").submit();
}

 

2. header.jspf와 sigIn.jsp를 연결해주기

- 홈페이지에서 로그인을 누르면 myappy/member/signIn 이렇게 넘어가야 한다.
- 여기서 {url} -> request.getContextPath( )로 myappy이다.
- header.jspf에서 로그인에 해당하는 a태그에 sigIn 주소 적기
<li><a href="${url}/member/signIn">로그인</a></li>

3. signIn.jsp 주소를 매핑할 MemberController생성 

package com.mycampus.myappy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

// 회원가입, 회원정보수정, 로그인, 로그아웃
@Controller
public class MemberController {

	// 로그인 폼(signIn.jsp)으로 이동하는 Mapping
	@GetMapping("/member/signIn")
	public String signIn() {
		return "member/signIn";  // /WEB-INF/views/member/signIn.jsp
	}
}
더보기

- return 할 때 폴더와 파일명만 적어주는 이유는 servlet-context.xml에 이미 적용해놓았기 때문이다!!

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
</beans:bean>

 - Mapping( ) 안에 "member/signIn" 이렇게 적으면 매핑이 안된다! 꼭 /를 적어주기!

- a태그로 이동하면 GetMapping으로 한다!


3. views(홈)에 회원가입 메뉴를 눌렀을 때 보일 회원가입 폼 만들기

1. views밑에 member 폴더 > signUp.jsp 파일 생성

- 아직 db와 연결을 안 했기 때문에 action이 실행되지 않는다.(memberOk 아직 실행 안됨)
- db의 컬럼명과 동일해야 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<link rel="stylesheet" href="/myappy/css/signUpStyle.css" type="text/css"/>
<script src="/myappy/js/signUpJs.js"></script>
<div class="container">
	<h1>회원가입 폼</h1>
	<hr/>
	<form method="post" action="/myappy/member/memberOk" id="signUpFrm" onsubmit="return signUpCheck()">
	<ul>
		<li>아이디</li>
		<li><input type="text" name="userid" id="userid" placeholder="아이디 입력"/>
			<input type="button" value="아이디 중복확인"/><!-- 나중에 ajax로 구현 -->
		</li>
		<li>비밀번호</li>
		<li><input type="password" name="userpwd" id="userpwd" placeholder="비밀번호 입력"/>
		<li>비밀번호 중복확인</li>
		<li><input type="password" name="userpwd2" id="userpwd2" placeholder="비밀번호 확인"/>
		<li>이름</li>
		<li><input type="text" name="username" id="username"/></li>
		<li>연락처</li>
		<li>
			<select name="tel1">
				<option value="010">010</option>
				<option value="02">02</option>
				<option value="031">031</option>
				<option value="051">051</option>
			</select> - 
			<input type="text" name="tel2" id="tel2" maxlength="4"> -
			<input type="text" name="tel3" id="tel3" maxlength="4"/>
		</li>
		<li>이메일</li>
		<li><input type="text" name="email" id="email"></li>
		<li><input type="submit" value="가입하기"/></li>
	</ul>
	</form>
</div>
더보기

signUpStyle.css

@charset "UTF-8";

#signUpFrm li{
	float:left;
	height:40px;
	line-height:40px;
	width:20%;
}
#signUpFrm li:nth-child(2n){
	width:80%;
}
#signUpFrm li:last-of-type {
	width:100%;
}

signUpJs.js

function signUpCheck(){
	// 아이디
	let userid = document.getElementById("userid");
	if(userid.value==""){
		alert("아이디를 입력하세요");
		userid.focus();
		return false;
	}
	
	// 비밀번호 확인( 1)입력확인 2)비밀번호 일치 확인 )
	let userpwd = document.getElementById("userpwd");
	let userpwd2 = document.querySelector("#userpwd2");
	
	if(userpwd.value=='' || userpwd2.value==''){
		alert("비밀번호를 입력하세요");
		userpwd.focus();
		return false;
	}
	if(userpwd.value != userpwd2.value){
		alert("비밀번호가 일치하지 않습니다.");
		userpwd2.focus();
		return false;
	}
	
	// 이름
	let username = document.querySelector("#username");
	if(username.value==''){
		alert("이름을 입력하세요");
		username.focus();
		return false;
	}
	
	// 전화번호
	let tel2 = document.querySelector("#tel2");
	let tel3 = document.querySelector("#tel3");
	
	if(tel2.value==""){
		alert("전화번호를 입력해주세요");
		tel2.focus();
		return false;
	}
	if(tel3.value==""){
		alert("전화번호를 입력해주세요");
		tel3.focus();
		return false;
	}
	
	let regExp = /^[0-9]{3,4}[0-9]$/; // tel2
	let regExp2 = /^[0-9]{4}$/;  // tel3
	if(!regExp.test(tel2.value)){
		alert("전화번호를 잘못 입력하였습니다. 다시 입력하세요");
		tel2.focus();
		return false;
	}
	if(!regExp2.test(tel3.value)){
		alert("전화번호를 잘못 입력하였습니다. 다시 입력하세요");
		tel3.focus();
		return false;
	}
}

2. header.jspf와 sigIn.jsp를 연결해주기

- 홈페이지에서 로그인을 누르면 myappy/member/signUp 이렇게 넘어가야 한다.
- header.jspf에서 로그인에 해당하는 a태그에 sigUp 주소 적기
<a href="${url}/member/signUp">회원가입</a>

3. MemberController에 signUp.jsp 주소 매핑

	// 회원가입 폼(signUp.jsp)으로 이동하는 Mapping 
	@GetMapping("/member/signUp")
	public String singUp() {
		return "member/signUp";
	}


4. 회원가입 폼에서 가입하기 버튼을 누르면 DB에 저장되게 하기

아이디, 비밀번호, 이름, 연락처, 이메일을 서버로 가져가야 한다. (Controller에서 request 해야 한다.)

-> VO나 매개변수를 사용해서 이름이 같은 것을 request 해줘야 한다. 

 

1. MemberVO를 DB의 컬럼명과 같게 만든다.

더보기
package com.mycampus.myappy.vo;

public class MemberVO {
	
	private String userid;
	private String userpwd;
	private String username;
	
	private String tel;
	private String tel1;
	private String tel2; 
	private String tel3;
	
	private String email;
	private String writedate;
	
	
	public String getUserid() {
		return userid;
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getUserpwd() {
		return userpwd;
	}
	public void setUserpwd(String userpwd) {
		this.userpwd = userpwd;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getTel() {
		// tel1, tel2, tel3를 하나의 데이터로 get할 때 만들어준다.
		// mybatis가 알아서 tel을 담는다.(DB와 이름이 같기 때문에)
		tel = tel1+"-"+tel2+"-"+tel3;
		return tel;
	}
	public void setTel(String tel) {
		// 값이 외부에서(문자열로) 들어오면 쪼개야한다.(tel을 쪼개기)
		// DB전화번호를 02-2345-9584를 잘라서 각각의 변수에 넣기
		String telSplit[] = tel.split("-");
		tel1 = telSplit[0];
		tel2 = telSplit[1];
		tel3 = telSplit[2];
		this.tel = tel;
	}
	public String getTel1() {
		return tel1;
	}
	public void setTel1(String tel1) {
		this.tel1 = tel1;
	}
	public String getTel2() {
		return tel2;
	}
	public void setTel2(String tel2) {
		this.tel2 = tel2;
	}
	public String getTel3() {
		return tel3;
	}
	public void setTel3(String tel3) {
		this.tel3 = tel3;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getWritedate() {
		return writedate;
	}
	public void setWritedate(String writedate) {
		this.writedate = writedate;
	}
	
}

2. memberInsert( )를 MemberDAO에 작성한다.

package com.mycampus.myappy.dao;

import com.mycampus.myappy.vo.MemberVO;

public interface MemberDAO {
	// 회원 등록 
	public int memberInsert(MemberVO vo); 
	// 매개변수로 데이터가 담겨져있는 VO클래스이다. 
	// 추가된 레코드의 수를 반환하기 때문에 int형
}

3. memberInsert( )를 MemberService interface에 작성한다.

package com.mycampus.myappy.service;

import com.mycampus.myappy.vo.MemberVO;

public interface MemberService {
	//회원등록
	public int memberInsert(MemberVO vo); 
}

4. memberInsert( )를 구현한 메서드를 MemberServiceimpl 파일에 작성한다.

package com.mycampus.myappy.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mycampus.myappy.dao.MemberDAO;
import com.mycampus.myappy.vo.MemberVO;

@Service
public class MemberServiceImpl implements MemberService {
	
	@Autowired 
	MemberDAO dao; // DAO의 memberInsert를 사용하기 위해서 DAO를 객체 생성
	
	@Override
	public int memberInsert(MemberVO vo) {
		return dao.memberInsert(vo);
	}

}

5. MemberMapper.xml에서 쿼리문을 작성한다.

환경설정 https://mybatis.org/mybatis-3/ko/getting-started.html 가서 매핑된 SQL 구문 살펴보기에서 코드 가져와서 mapper xml 파일 상단에 위치

<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

DB 순서대로 써야 하고, 주석 문은 쓰지 않는다.

문자열일 때는 주로 # 숫자일 때는 주로 $ (선택적으로 사용한다.)

values(#{userid})
데이터가 홑따옴표가 적용된다. ('goguma') 
values(${userid})
홑따옴표 적용안된다.(숫자일때 사용) (goguma)
<?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="com.mycampus.myappy.dao.MemberDAO">
	<insert id="memberInsert">
		insert into member(userid, userpwd, username, tel, email) 
		values(#{userid}, #{userpwd}, #{username}, #{tel}, #{email})
	</insert>
</mapper>

 

6. MemberController에서 memberOk Mapping(signUp.jsp form의 액션)

	// 회원 가입
	// @RequestMapping(value="/member/memberOk", method=RequestMethod.POST)
	@PostMapping("/member/memberOk")
	public String memberFormOk(MemberVO vo, Model model) { 
		// 회원등록하기 위해 memberInsert()
		int cnt = service.memberInsert(vo);
		
		// cnt에서 돌아온 결과(0 or 1)를 model에 저장 
		model.addAttribute("cnt", cnt);
		return "member/signUpResult";   // 클라이언트 페이지로 insert 결과를 보낸다.
	}
    
    
    // signUp.jsp 
    <form method="post" action="/myappy/member/memberOk" id="signUpFrm" onsubmit="return signUpCheck()">
- memberOk의 첫 번째 매개변수: 클라이언트가 보낸 정보(아이디, 비밀번호, 이름, 전화번호 등)를 담아온다.
- memberOk의 두 번째 매개변수: 정보를 model에 저장한다.
- model에 저장할 때는 addAttribute( )를 사용한다. 
- signUpResult 파일을 생성해서 결과가 0이면 회원가입 실패 결과가 1이면 회원가입 성공 

6-1. signUpResult.jsp 파일을 생성해서 cnt 결과를 가지고 성공했을 때 실패했을 때로 나눈다. 

cnt의 결과가 0이면 회원가입 실패(history.back: 회원가입 폼) 1이면 회원가입 성공(로그인 페이지)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 스쳐가는 페이지이기 때문에 html 필요xx -->
<!-- cnt를 가지고 등록된 경우, 등록 안 된 경우로 나눈다.  -->

<!-- 등록시 -->
<c:if test="${cnt>0}">
	<script>
		alert("회원으로 등록되었습니다. 로그인 페이지로 이동합니다.");
		location.href="/myappy/member/signIn";
	</script>
</c:if>

<!-- 등록 실패시 -->
<c:if test="${cnt==null || cnt==0}">
	<script>
		alert("회원등록에 실패하였습니다.");
		history.go(-1);
	</script>
</c:if>

6-2. 서버를 실행하면 DB에 잘 들어간 것을 확인할 수 있다.