0. 무엇보다 회원 데이터를 위해, 새로운 데이터 테이블을 생성 사용할 것이므로,
기존 BoderVO파일이 있는 패키지에, UserVO 파일 생성.(사용할 데이터베이스 테이블을 먼저 만들어 둔다.)
package com.project.model;
public class UserVO {
private String id; // 유저 아이디
private String pwd; // 비밀번호
private String nick; // 닉네임
private String ncode; // 국가
private String email; // 이메일
private String text; // 추가 텍스트
private String channel; // 채널 정보
private int scount; // 카운트 정보
private String etc1; // 기타 정보 1
private int etc2; // 기타 정보 2
private String etc3; // 기타 정보
// `etc4` longblob, // 기타 정보(대용량파일 관련)
private String etc5; // 기타 정보
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getNcode() {
return ncode;
}
public void setNcode(String ncode) {
this.ncode = ncode;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public int getScount() {
return scount;
}
public void setScount(int scount) {
this.scount = scount;
}
public String getEtc1() {
return etc1;
}
public void setEtc1(String etc1) {
this.etc1 = etc1;
}
public int getEtc2() {
return etc2;
}
public void setEtc2(int etc2) {
this.etc2 = etc2;
}
public String getEtc3() {
return etc3;
}
public void setEtc3(String etc3) {
this.etc3 = etc3;
}
public String getEtc5() {
return etc5;
}
public void setEtc5(String etc5) {
this.etc5 = etc5;
}
}
사용할 데이터 테이블의 컬럼들을 나열하고, 게터와 세터로 자료를 정렬해둔다.
1. 보통 회원가입은 메인 페이지에 나오니까, 링크를 하나 걸어 둔다.
home.jsp파일에
<a href="/account/join">회원가입</a>
2. 그럼 먼저 join.jsp(V)파일을 건드려 준다.
view폴더에 account라는 폴더 생성 후, join.jsp파일을 생성한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<!-- jquery 사용 -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<title>회원가입</title>
<style>
.help-block{
color:red;
}
</style>
</head>
<body>
<section id="container">
<form method="post">
<!-- 아래나오는 클래스들은 부트스트랩 테마로 사용됨. -->
<div class="form-group has-feedback">
<label class="control-label" for="id">아이디</label>
<input class="form-control" type="text" id="id" name="id" required/>
<button type="button" id="checkIdBtn">아이디 중복확인</button>
<!-- 그리고 버튼 #을 사용해서 중복확인 로직을 만들어 줌. -->
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pwd">패스워드</label>
<input class="form-control" type="password" id="pwd" name="pwd" required/>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="confirmPwd">패스워드 확인</label>
<input class="form-control" type="password" id="confirmPwd" name="confirmPwd" required/>
<span id="passwordMatchMessage" class="help-block"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="nick">닉네임</label>
<input class="form-control" type="text" id="nick" name="nick" required/>
<button type="button" id="checkNickBtn">닉네임 중복확인</button>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="email">이메일</label>
<input class="form-control" type="email" id="email" name="email" required/>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="ncode">국가</label>
<select class="form-control" id="ncode" name="ncode" required>
<option value="">선택하세요</option>
<!-- option태그로 선택지를 만들어 사용. -->
<!-- 데이터베이스 단에서 데이터 받아서 뷰로 출력 -->
<c:forEach items="${countryCodes}" var="code">
<option value="${code}">${code}</option>
</c:forEach>
</select>
</div>
<div class="form-group has-feedback">
<button class="btn btn-success" type="submit" id="submit" disabled>회원가입</button>
<!-- disabled 속성으로 중복확인 안되면 사용 불가능하게 만듦. -->
<button class="cancle btn btn-danger" type="button">취소</button>
</div>
</form>
</section>
<script type="text/javascript">
var idChecked = false;
var nickChecked = false;
var pwdChecked = false;
$(document).ready(function(){
// 취소
$(".cancle").on("click", function(){
location.href = "/";
});
})
// 패스워드 확인
$("#confirmPwd").keyup(function() {
var password = $("#pwd").val();
var confirmPassword = $(this).val();
if (password !== confirmPassword) {
$("#passwordMatchMessage").text("패스워드가 일치하지 않습니다.");
pwdChecked = false;
} else {
$("#passwordMatchMessage").text("패스워드가 일치합니다.");
pwdChecked = true;
}
});
/* 아이디와 닉네임 중복확인을 위한 js사용 */
$(document).ready(function() {
$("#checkIdBtn").click(function() {
var id = $("#id").val();
if (id === "") {
alert("아이디를 입력해주세요.");
$("#id").focus();
return;
}
$.ajax({
type: "POST",
url: "/checkId",
data: { id: id },
success: function(response) {
if (response=="available") {
alert("사용 가능합니다.");
idChecked = true;
checkSubmitButton();
} else {
alert("중복되는 아이디입니다.");
idChecked = false;
checkSubmitButton();
}
},
error: function() {
alert("서버와 통신 중 오류가 발생했습니다.");
}
});
});
});
$(document).ready(function() {
$("#checkNickBtn").click(function() {
var nick = $("#nick").val();
if (nick === "") {
alert("닉네임을 입력해주세요.");
$("#nick").focus();
return;
}
$.ajax({
type: "POST",
url: "/checkNick",
data: { nick: nick },
success: function(response) {
if (response=="available") {
alert("사용 가능합니다.");
nickChecked = true;
checkSubmitButton();
} else {
alert("중복되는 닉네임입니다.");
nickChecked = false;
checkSubmitButton();
}
},
error: function() {
alert("서버와 통신 중 오류가 발생했습니다.");
}
});
});
});
function checkSubmitButton() {
if (idChecked && nickChecked && pwdChecked) {
$("#submit").prop("disabled", false);
} else {
$("#submit").prop("disabled", true);
}
}
</script>
</body>
</html>
3. 그리고 이 jsp파일을 가운데서 컨트롤 할
UserController파일을 따로 생성.(회원 시스템이므로 따로 컨트롤러 생성)
package com.project.controller;
import java.util.List;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.ui.Model;
import com.project.model.UserVO;
import com.project.service.UserService;
@Controller
public class UserController {
// @Inject와 @Autowired는 비슷하게 의존성 자동 주입 기능을 하는 어노테이션인데;
// @Autowired는 스프링에 특화됨. 일반적이로 스프링에서 사용.
@Autowired
private UserService userService;
// @RequestMapping(value = "/account/join", method = RequestMethod.GET)
// @GetMapping("/account/join")
// @RequestMapping 이것으로 모두 통합적 사용했으나,(아직 기업에서는 이것을 사용할 듯하다)
// @GetMapping 더 직관적으로 업그레이드. 일반적으로 4.3 이상 버전에서 사용.
@GetMapping("/account/join")
public void getJoin(Model model) throws Exception{
// 회원가입 페이지를 보여주는 겟코드
// 국가 코드 리스트를 가져와서 JSP에 전달
List<String> countryCodes = null;
countryCodes = userService.getCountryCodes();
model.addAttribute("countryCodes", countryCodes);
}
@PostMapping("/account/join")
public String joinProcess(UserVO userVo) {
// 회원가입 처리 코드
try {
userService.join(userVo);
} catch (Exception e) {
// 예외 처리 로직 추가
e.printStackTrace();
// 실패 시 에러 페이지 또는 회원가입 실패 페이지로 이동하도록 처리
return "error-page";
}
// 회원가입 성공 시 홈으로 리다이렉트
return "redirect:/";
}
@PostMapping("/checkId")
@ResponseBody
// @ResponseBody 메서드 반환 값을 HTTP로 직접 반환.
public String checkId(@RequestParam String id) throws Exception {
// ID 중복 확인 로직을 구현합니다.
// 중복되는 ID가 있는 경우 "duplicate"를 반환하고, 사용 가능한 ID인 경우 "available"을 반환합니다.
if (userService.isIdDuplicated(id)) {
return "duplicate";
} else {
return "available";
}
}
@PostMapping("/checkNick")
@ResponseBody
public String checkNick(@RequestParam String nick) throws Exception {
if (userService.isNickDuplicated(nick)) {
return "duplicate";
} else {
return "available";
}
}
}
4. 그렇다면 이제 매퍼. 회원 시스템이니까 이것도 따로 만들어준다.
기존 매퍼가 있는 폴더에 accountMapper.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.mappers.account">
<!-- 회원가입 -->
<insert id="join" parameterType="com.project.model.UserVO">
insert into
user(id, pwd, nick, ncode, email)
values(#{id}, #{pwd}, #{nick}, #{ncode}, #{email} )
</insert>
<!-- 중복 확인 시스템 -->
<select id="isIdDuplicated" parameterType="java.lang.String" resultType="java.lang.Integer">
SELECT COUNT(*) FROM projects.user WHERE id = #{id}
</select>
<select id="isNickDuplicated" parameterType="java.lang.String" resultType="java.lang.Integer">
SELECT COUNT(*) FROM projects.user WHERE nick = #{nick}
</select>
<!-- 국가 선택지 데이터베이스 셀렉트 -->
<select id="getCountryCodes" resultType="java.lang.String">
SELECT code_en FROM nation ORDER BY code_en;
</select>
</mapper>
국가 선택지 테이블도 사용해보려고 따로 만들었다. 인터넷 자료 참고해서 데이터는 구축하면 된다.
5. 마지막으로 DAO와 Service 파일에 추가
UserDAO, UserDAOImpl, UserService, UserServiceImpl 파일을 기존의 model과 service패키지에 추가로 만들어 준다.
package com.project.model;
import java.util.List;
public interface UserDAO {
public void join(UserVO vo) throws Exception;
public boolean isIdDuplicated(String id);
public boolean isNickDuplicated(String nick);
public List<String> getCountryCodes();
}
UserService는 UserDAO와 인터페이스 이름만 다르고 나머지 모두 같다.
그리고, UserDAOImpl 파일에는 아래 코드 추가(실제로 데이터베이스와 상호작용하는 녀석)
package com.project.model;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserDAOImpl implements UserDAO {
@Autowired
private SqlSession sqlSession;
private static String namespace = "com.project.mappers.account";
@Override
public void join(UserVO vo) throws Exception {
// TODO Auto-generated method stub
sqlSession.insert(namespace + ".join", vo);
}
@Override
public boolean isIdDuplicated(String id) {
// TODO Auto-generated method stub
int count = sqlSession.selectOne(namespace + ".isIdDuplicated", id);
return count > 0;
}
@Override
public boolean isNickDuplicated(String nick) {
// TODO Auto-generated method stub
int count = sqlSession.selectOne(namespace + ".isNickDuplicated", nick);
return count > 0;
}
// 국가 코드 리스트를 가져오는 메서드 추가
public List<String> getCountryCodes() {
return sqlSession.selectList(namespace + ".getCountryCodes");
}
}
그리고, UserServiceImpl 파일에는 아래 코드 추가(간접적 상호작용. 보안효과)
package com.project.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.project.model.UserDAO;
import com.project.model.UserVO;
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Override
public void join(UserVO vo) throws Exception {
userDAO.join(vo);
}
@Override
public boolean isIdDuplicated(String id) {
// 데이터베이스에서 아이디 중복 확인 로직을 구현하고 결과를 반환합니다.
// 예를 들어, 아이디가 이미 존재하면 true, 존재하지 않으면 false를 반환하도록 구현합니다.
return userDAO.isIdDuplicated(id);
}
@Override
public boolean isNickDuplicated(String nick) {
// 데이터베이스에서 아이디 중복 확인 로직을 구현하고 결과를 반환합니다.
// 예를 들어, 아이디가 이미 존재하면 true, 존재하지 않으면 false를 반환하도록 구현합니다.
return userDAO.isNickDuplicated(nick);
}
@Override
public List<String> getCountryCodes() {
return userDAO.getCountryCodes();
}
}
확인. 나이스.
'Programming > 스프링(spring) - Enterprise' 카테고리의 다른 글
스프링(spring)/ 회원 시스템 구축 3(회원정보 수정 및 탈퇴) (0) | 2023.08.01 |
---|---|
스프링(spring)/ 회원 시스템 구축 2(로그인 페이지) (0) | 2023.08.01 |
스프링(spring)/ 게시판 구축 5(좋아요 기능) (0) | 2023.07.21 |
스프링(spring)/ 게시판 구축 4(검색 기능) (0) | 2023.07.20 |
스프링(spring)/ 게시판 구축 3(게시물 수정 및 삭제) (0) | 2023.07.20 |