Zara) 회원가입 페이지 만들기
제가 맡은 회원 부분에서 제일 먼저 만들 부분입니다.
#회원가입 페이지에서 구현할 기능
1. 회원가입 창에서 빈칸이 있을 시 회원가입을 못하도록 설정했습니다.
2. 중복 체크 버튼을 누를 시 ajax를 통해서 합니다.
3. 주소는 카카오 주소 api를 사용합니다.
4 . 회원가입 버튼을 눌렀을 시 비밀번호와 비밀번호 재입력이 일치하지 않으면 다시 입력하도록 합니다.
# Member ERD, Member VO 만들기
우선 회원가입 페이지에 앞서
회원 정보를 담을 Erd와 VO 부터 설계해보도록하겠습니다!
회원아이디를 기본키로 받고
그 외 개인 정보를 담습니다.
주소는 카카오 api를 사용할 예정이므로 도로명 주소, 상세주소 , 우편번호로 나누었습니다.
MemberVO
package com.project.zara.model;
import java.sql.Date;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MemberVO {
private String mem_id; // 회원아이디
private String mem_password; // 회원 비밀번호
private String mem_name; // 회원 이름
private String mem_tel; // 전화번호
private String mem_email; // 이메일
private String mem_zip; // 우편번호
private String mem_road; // 도로명 주소
private String mem_adrdetail; // 상세 주소
private String gender; // 성별
private Date create_at; // 생성일자
private Date update_at; // 수정일자
private Date last_login; // 마지막 로그인 일자
private String delete_flag; // 삭제여부
private Date delete_at; // 삭제일자
private int mem_point; //포인트
}
# register.jsp 만들기
회원가입 페이지는 친구가 설계해준걸 토대로 만들었습니다.
페이지마다 중복 될 Top , SideMenu 부분은 jspf로 만들어서 include 방식으로 했습니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>회원가입</title>
<!-- 부트 스트랩 부분 -->
<%@include file="../../include/boot-head.jspf" %>
<style type="text/css">
#logo {
width: 100px;
height: 60px;
}
.btn-user {
margin-left : 830px;
width: 500px;
}
.card {
margin : auto;
width: 600px;
}
.card-body {
margin-top : 30px;
}
.form-group label {
font-size : 15px;
margin-right: 20px;
width: 110px;
margin-bottom: 25px;
}
.form-group li {
list-style: none;
}
.form-group input {
font-size: 15px;
}
#checkId {
margin-left : 10px;
height: 35px;
width: 90px;
font-size: 15px;
text-align: center;
}
#woman {
margin-left: 10px;
}
.address_form input {
margin-bottom: 10px;
margin-right: 10px;
}
</style>
</head>
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<%@include file="../../include/sidemenu.jspf" %>
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Toolbar -->
<%@include file="../../include/toolbar.jspf" %>
<div class="card">
<article class="card-body">
<h4 class="card-title text-center mb-4 mt-1">회원가입</h4>
<hr>
<p class="text-success text-center">다양한 서비스를 이용하시려면 회원가입 해주세요</p>
<form id="register_form" name="register_form" method="post" action="/user/register">
<div class="form-group">
<ul>
<li>
<label>아이디</label>
<input id="id" placeholder="아이디를 입력해주세요" required="required" name="id">
<button id="checkId" class="btn btn-primary" type="button">중복체크</button>
</li>
<li>
<label>비밀번호</label>
<input type="password" id="password" placeholder="비밀번호를 입력해주세요" required="required" name="password">
</li>
<li>
<label>비밀번호 재입력</label>
<input type="password" id="password2" placeholder="비밀번호를 입력해주세요" required="required" name="password2">
</li>
<li>
<label>이름</label>
<input placeholder="이름을 입력해주세요" required="required" name="name">
</li>
<li>
<label>전화번호</label>
<input placeholder="전화번호를 입력해주세요" required="required" name="tel">
</li>
<li>
<label>이메일</label>
<input placeholder="이메일을 입력해주세요" required="required" name="email">
</li>
<li>
<label>주소</label>
<div class="address_form">
<input name="mem_zip" type="text" id="sample4_postcode" placeholder="우편번호">
<input type="button" onclick="sample4_execDaumPostcode()" value="우편번호 찾기"><br>
<input name="mem_road" type="text" id="sample4_roadAddress" placeholder="도로명주소">
<span id="guide" style="color:#999;display:none"></span>
<input name="mem_adrdetail" type="text" id="sample4_detailAddress" placeholder="상세주소">
</div>
</li>
<li>
<label>성별</label>
<input type="radio" placeholder="성별을 입력해주세요" required="required" name="gender" value="남">남
<input id="woman" type="radio" placeholder="내용을 입력해주세요" required="required" name="gender" value="여">여
</li>
</ul>
</div> <!-- form-group// -->
<div class="form-group">
<button id="btn_register" type="button" class="btn btn-primary btn-block">회원가입</button>
</div> <!-- form-group// -->
</form>
</article>
</div> <!-- card.// -->
</div>
</div>
<!-- End of Toolbar -->
</div>
<!-- End of Page Wrapper -->
<!-- 부트스트랩 js 부분 -->
<%@include file="../../include/boot-footer.jspf" %>
<script>
var passwordInput = document.getElementById('password');
var passwordInput2 = document.getElementById('password2');
var register_form = document.register_form;
var btn_check = document.getElementById('checkId');
var check_id_flag = 0;
var btn_register = document.getElementById('btn_register');
btn_register.addEventListener('click',function() {
if(document.register_form.id.value ==""){
alert("아이디를 입력해주세요!");
}
else if(document.register_form.password.value =="") {
alert("비밀번호를 입력해주세요!");
}
else if(document.register_form.name.value =="") {
alert("이름을 입력해주세요!");
}
else if(document.register_form.tel.value =="") {
alert("전화번호를 입력해주세요!");
}
else if(document.register_form.email.value =="") {
alert("이메일 입력해주세요!");
}
else if(document.register_form.mem_adrdetail.value =="") {
alert("상세주소를 입력해주세요!");
}
else if(document.register_form.gender.value =="") {
alert("성별을 입력해주세요!");
}
else {
var password = passwordInput.value;
var password2 = passwordInput2.value;
if(password !== password2) {
alert("비밀번호가 일치하지 않습니다.");
passwordInput.value = "";
passwordInput2.value = "";
passwordInput.focus();
}
else {
if(check_id_flag == 0 )
alert("중복체크 해주세욧!");
else
register_form.submit();
}
}
});
btn_check.addEventListener('click', function(){
var idInput =document.getElementById('id');
var id =idInput.value;
$.ajax({
url : "/user/checkId",
type : "post",
dataType : 'text',
data : {
id : id
},
success : function(result) {
console.log("결과 :" +result);
if(result == '0'){
alert("사용할 수 있는 아이디 입니다.");
check_id_flag =1;
}
else if(result =="1") {
check_id_flag =1;
alert("중복된 아이디 입니다..");
}
},
error : function(xhr,status,error) {
console.log(error);
console.log(xhr);
console.log(status);
}
});
});
</script>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
function sample4_execDaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
// 예제를 참고하여 다양한 활용법을 확인해 보세요.
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 도로명 주소의 노출 규칙에 따라 주소를 표시한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var roadAddr = data.roadAddress; // 도로명 주소 변수
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('sample4_postcode').value = data.zonecode;
document.getElementById("sample4_roadAddress").value = roadAddr;
var guideTextBox = document.getElementById("guide");
// 사용자가 '선택 안함'을 클릭한 경우, 예상 주소라는 표시를 해준다.
if(data.autoRoadAddress) {
var expRoadAddr = data.autoRoadAddress + extraRoadAddr;
guideTextBox.innerHTML = '(도로명 주소 : ' + expRoadAddr + ')';
guideTextBox.style.display = 'block';
} else if(data.autoJibunAddress) {
var expJibunAddr = data.autoJibunAddress;
guideTextBox.innerHTML = '(지번 주소 : ' + expJibunAddr + ')';
guideTextBox.style.display = 'block';
} else {
guideTextBox.innerHTML = '';
guideTextBox.style.display = 'none';
}
}
}).open();
}
</script>
</body>
</html>
카카오 Api 사용법
https://postcode.map.daum.net/guide
우선 에 접속하여 원하는 방식의 사용법을 확인합니다!
저는 아래의 코드를 이용했습니다!
Daum 우편번호 서비스
우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무료로 제약없이 사용 가능하답니다.
postcode.map.daum.net
1 . js 추가
```js
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
function sample4_execDaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
// 예제를 참고하여 다양한 활용법을 확인해 보세요.
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 도로명 주소의 노출 규칙에 따라 주소를 표시한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var roadAddr = data.roadAddress; // 도로명 주소 변수
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('sample4_postcode').value = data.zonecode;
document.getElementById("sample4_roadAddress").value = roadAddr;
var guideTextBox = document.getElementById("guide");
// 사용자가 '선택 안함'을 클릭한 경우, 예상 주소라는 표시를 해준다.
if(data.autoRoadAddress) {
var expRoadAddr = data.autoRoadAddress + extraRoadAddr;
guideTextBox.innerHTML = '(도로명 주소 : ' + expRoadAddr + ')';
guideTextBox.style.display = 'block';
} else if(data.autoJibunAddress) {
var expJibunAddr = data.autoJibunAddress;
guideTextBox.innerHTML = '(지번 주소 : ' + expJibunAddr + ')';
guideTextBox.style.display = 'block';
} else {
guideTextBox.innerHTML = '';
guideTextBox.style.display = 'none';
}
}
}).open();
}
</script>
```
2. input 추가
```html
<li>
<label>주소</label>
<div class="address_form">
<input name="mem_zip" type="text" id="sample4_postcode" placeholder="우편번호">
<input type="button" onclick="sample4_execDaumPostcode()" value="우편번호 찾기"><br>
<input name="mem_road" type="text" id="sample4_roadAddress" placeholder="도로명주소">
<span id="guide" style="color:#999;display:none"></span>
<input name="mem_adrdetail" type="text" id="sample4_detailAddress" placeholder="상세주소">
</div>
</li>
```
# Member Controller
1. 요청 주소 : user/register (GET방식) : register.jsp를 보여줄 수는 주소입니다.
2. user/register(POST방식) : 기입을 다 한 후 회원가입 버튼을 눌렀을 시 POST방식으로 데이터를 넘겨준 후 insert문을 실행합니다.
3. user/checkId(POST방식) : ajax로 아이디를 체크 합니다.
package com.project.zara.controller;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.project.zara.mapper.MemberMapper;
import com.project.zara.model.MemberVO;
import com.project.zara.service.MemberService;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
@RequestMapping("/user")
public class MemberController {
// 회원가입 페이지 보여주기
@RequestMapping(path = "/register", method=RequestMethod.GET)
public String Register() {
return "user/register";
}
// 회원가입 시 중복 체크
@RequestMapping(path = "/checkId", method=RequestMethod.POST)
@ResponseBody
public String checkId(@RequestParam("id") String id){
return memberService.checkId(id);
}
// 회원가입 시도
@RequestMapping(path = "/register", method=RequestMethod.POST)
public String doRegister(@RequestParam Map<String,Object> param ,Model model) {
String msg = "회원가입에 성공하셨습니다.";
String url = "/";
memberService.doRegister(param);
model.addAttribute("msg",msg);
model.addAttribute("url",url);
return "common/redirect";
}
}
# MemberService
package com.project.zara.service;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import com.project.zara.model.MemberVO;
public interface MemberService {
public void doRegister(Map<String,Object> param);
public String checkId(String id);
}
# MemberServiceImpl
package com.project.zara.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.project.zara.mapper.MemberMapper;
import com.project.zara.model.MemberVO;
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
MemberMapper memberMapper;
@Override
public void doRegister(Map<String, Object> param) {
memberMapper.doRegister(param);
}
@Override
public String checkId(String id) {
// TODO Auto-generated method stub
return memberMapper.checkId(id);
}
# MemberMapper
package com.project.zara.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.project.zara.model.MemberVO;
@Mapper
public interface MemberMapper {
public void doRegister(Map<String, Object> param);
public String checkId(@Param("id") String id);
}
# 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="com.project.zara.mapper.MemberMapper">
<!-- 회원가입 -->
<insert id="doRegister" parameterType="map" useGeneratedKeys="true" keyProperty="mem_id">
insert into member VALUES(
#{id},
#{password},
#{name},
#{tel},
#{email},
#{mem_zip},
#{mem_road},
#{mem_adrdetail},
#{gender},
sysdate,
null,
null,
'N',
null,
0
)
</insert>
<!-- 아이디 중복 체크 -->
<select id="checkId" parameterType="String" resultType="String">
select count(*) from member where mem_id = #{id}
</select>
</mapper>
아이디 중복 체크는 count로 하여 입력한 아이디가 count가 0이 아니면 중복된 아이디임을 알려주도록 했습니다.