프로젝트/Staffriends 프로젝트

[Staffriends 프로젝트] (1) 회원 CRUD 구현하기 - 1. 회원가입

sungw00 2023. 5. 22. 02:37
728x90

회원가입

1. 회원 CRUD를 구현하기 위해 UserVO 클래스를 작성

package board.vo;

import lombok.Data;

@Data
public class UserVo {
    private String username; // 아이디
    private String name; // 이름
    private String password; // 비밀번호
    private String nickname; // 닉네임
    private String email; // 이메일
    private String joinDate; // 가입일
    private String serialNum; // 시리얼 번호
    private String oauth; // oauth 여부
}

getter, setter, toString 등의 메서드를 자동으로 생성해주는 @Data 어노테이션을 사용하기 위해 lombok 라이브러리를 import 해주었고, 이로인해 코드의 양이 확실하게 줄었다. 

각 필드의 이름은 우측에 있는 주석과 대응된다.

 

롬복을 사용하기 위해 IntelliJ -> Settings -> Plugins에서 lombok을 설치해주었다.

 

2. UserController 작성

UserVO를 생성했다면 이번에는 UserController를 생성하여 회원 전반적인 기능에 대응할 수 있도록 한다.

회원에 대한 기본적인 기능을 떠올리면 다음과 같이 네 가지를 떠올릴 수 있다.

  • 회원가입(Create)
  • 회원조회(Read)
  • 회원수정(Update)
  • 회원삭제(Delete)

가장 첫 번째 기능인 회원가입을 진행할 수 있도록 회원가입 페이지로 이동하는 메서드를 작성해보자.

package board.controller;

import board.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import board.vo.UserVo;

@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/joinForm") // 회원가입 페이지
    public String join() {
        return "/user/joinForm";
    }

@Controller 어노테이션을 작성하여 스프링 빈에 자동으로 등록될 수 있도록 한다.(@Controller 클래스에는 @Component 어노테이션이 포함되어 있기 때문이다.) 이렇게 하면 UserController는 스프링 컨테이너에 등록되어 스프링 빈으로써 스프링 컨테이너가 관리하기 시작한다.

Controller.java 클래스 내부 코드

 

위에서 등록한 join 메서드로 접근하기 위해서는 주소창으로부터 ① /user/joinForm이라는 주소를 요청받아야 하고, 결과로 ② /user/joinForm.jsp를 반환한다. 

 

3. UserService, UserServiceImpl, UserMapper 작성

UserService.java

package board.service;

import board.vo.UserVo;
import org.springframework.stereotype.Service;

@Service
public interface UserService {
    void insertUser(UserVo userVo) throws Exception;
    int idCheck(String username) throws Exception;

UserServiceImpl.java

package board.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import board.vo.UserVo;
import board.mapper.UserMapper;

import java.io.*;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.Map;

@Repository
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void insertUser(UserVo userVo) throws Exception { // 비밀번호 암호화 후 회원가입 진행
        messageDigest(userVo, userVo.getPassword());
        userMapper.insertUser(userVo);
    }

    @Override
    public int idCheck(String username) throws Exception { // 중복 아이디 확인
        return userMapper.idCheck(username);
    }

messageDigest 메서드 부분은 비밀번호 암호화 부분에서 작성할 예정이다.

 

UserMapper.java

package board.mapper;

import org.apache.ibatis.annotations.Mapper;
import board.vo.UserVo;

@Mapper
public interface UserMapper {
    void insertUser(UserVo userVo) throws Exception;
    int idCheck(String username) throws Exception;

 

4. /user/joinForm.jsp 생성

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="../layout/header.jsp"%>
<title>회원가입</title>
<html>
<body>
<h2 style="text-align: center; margin-top: 30px; margin-bottom: 70px; font-family: KakaoBold;">회원가입</h2>
<section style="padding-bottom: 50px;">
<div class="container center-div">
<form id="joinFrm" method="post" class="container center-div container-size">
    <div class="form-group">
        <h5>아이디</h5><input type="text" class="form-control" placeholder="영문 대/소문자, 숫자, 언더바/하이픈 포함 7~20자" name="username" id="username" style="text-align: center" oninput="idCheck(), activateSignupBtn()">
        <span style="display: none; text-align: center; color: red; " id="invalidId">영문 대/소문자, 숫자, 언더바/하이픈 포함 7~20자로 입력해야합니다.</span>
        <span style="display: none; text-align: center; color: red; " id="duplicateId">이미 사용중인 ID입니다.</span>
        <span style="display: none; text-align: center; color: red; " id="notInputId">ID를 입력해주세요.</span>
        <span style="display: none; text-align: center; color: green; " id="validId">사용이 가능한 ID입니다.</span>
    </div>
    <div class="form-group">
        <h5>비밀번호</h5><input type="password" class="form-control" placeholder="문자/숫자 포함 8자리 이상" name="password" id="password" style="text-align: center" oninput="pwCheck()">
        <span style="display: none; text-align: center; color: red; " id="notInputPw">비밀번호를 입력해주세요.</span>
        <span style="display: none; text-align: center; color: red; " id="invalidPw">문자/숫자 포함 8자리 이상 입력해야합니다.</span>
    </div>
    <div class="form-group">
        <h5>비밀번호확인</h5><input type="password" class="form-control" placeholder="비밀번호를 한번 더 입력하세요." name="samePassword" id="samePassword" style="text-align: center" oninput="samePwCheck(), activateSignupBtn()">
        <span style="display: none; text-align: center; color: red; " id="notInputSamePw">비밀번호를 한번 더 입력해주세요.</span>
        <span style="display: none; text-align: center; color: red; " id="invalidSamePw">문자/숫자 포함 8자리 이상 입력해야합니다.</span>
        <span style="display: none; text-align: center; color: red;" id="notSamePw">비밀번호가 일치하지 않습니다.</span>
        <span style="display: none; text-align: center; color: green;" id="validSamePw">비밀번호가 일치합니다.</span>
    </div>
    <div class="form-group">
        <h5>닉네임</h5><input type="text" class="form-control" placeholder="한글, 영문 대/소문자, 숫자 포함 2~15자" name="nickName" id="nickname" style="text-align: center" oninput="nicknameCheck(), activateSignupBtn()">
        <span style="display: none; text-align: center; color: red;" id="notInputNickname">닉네임을 입력해주세요.</span>
        <span style="display: none; text-align: center; color: red;" id="invalidNickname">한글, 영문 대/소문자, 숫자 포함 2~15자로 입력해야합니다.</span>
        <span style="display: none; text-align: center; color: green;" id="validNickname">사용 가능한 닉네임입니다.</span>
    </div>
    <div class="form-group">
        <h5>이메일</h5><input type="text" class="form-control" placeholder="이메일을 입력하세요." name="email" id="email" style="text-align: center" oninput="emailCheck(), activateSignupBtn()">
        <span style="display: none; text-align: center; color: red;" id="notInputEmail">이메일을 입력해주세요.</span>
        <span style="display: none; text-align: center; color: red;" id="invalidEmail">이메일 형식이 올바르지 않습니다.</span>
        <span style="display: none; text-align: center; color: green;" id="validEmail">사용 가능한 이메일입니다.</span>
    </div>
    <div class="form-group">
        <h5>이름</h5><input type="text" class="form-control" placeholder="이름을 입력하세요" name="name" id="name" style="text-align: center" oninput="nameCheck(), activateSignupBtn()">
        <span style="display: none; text-align: center; color: red;" id="notInputName">이름을 입력해주세요.</span>
        <span style="display: none; text-align: center; color: red;" id="invalidName">이름을 올바르게 입력해주세요.</span>
        <span style="display: none; text-align: center; color: green;" id="validName">사용 가능한 이름입니다.</span>
    </div>
    <div class="form-group">
        <h5>시리얼번호</h5><input type="text" class="form-control" placeholder="시리얼번호를 입력하세요(선택)" name="serialNum" id="serialNum" style="text-align: center">
    </div>
    <div class="form-group text-center">
        <input class="btn btn-staffriends  btn-lg center-div" type="button" value="회원가입" id="joinBtn" onclick="join()" disabled>
    </div>
</form>
</div>
</section>
</body>
<%@ include file="../layout/footer.jsp"%>
</html>

 

위 코드를 적용한 회원가입 페이지를 호출하면 아래와 같은 페이지가 호출 된다.

모든 정보를 입력한 후 회원가입 버튼을 클릭하게 되면 user.js의 join 메서드가 호출되어 이름, 비밀번호, 닉네임, 이메일, 이름, 시리얼번호를 json 형태로 변환하여 ajax 요청을 보내게 된다.

function join() { // 회원가입
    const username = document.getElementById('username').value;
    const password = document.getElementById('password').value;
    const nickname = document.getElementById('nickname').value;
    const email = document.getElementById('email').value;
    const name = document.getElementById('name').value;
    const serialNum = document.getElementById('serialNum').value;

    // 유효성 검사 완료 후 실행할 로직
    let data = {
        username:username,
        password:password,
        nickname:nickname,
        email:email,
        name:name,
        serialNum:serialNum
    };

    let xhr = new XMLHttpRequest();
    xhr.open("POST", "/user/join/insert");
    xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    xhr.onload = function() {
        if (xhr.status === 200 || xhr.status === 201) {
            let resp = xhr.responseText;
            console.log("resp:"+resp);
            if (resp.status === 500) {
                alert("에러가 발생했습니다.");
            } else {
                if (resp === "success") {
                    alert("회원가입이 완료되었습니다.");
                    location.href = "/";
                } else {
                    alert("회원가입을 완료하지 못했습니다.");
                }
            }
        } else {
            console.log(xhr.responseText);
            alert("에러가 발생했습니다. \n에러 코드: " + xhr.status);
        }
    };
    xhr.onerror = function() {
        alert("에러가 발생했습니다. \n에러 코드: " + xhr.status);
    };
    xhr.send(JSON.stringify(data));
}
  1. xhr.open("POST", "/user/join/insert"): POST 요청으로 /user/join/insert에 요청을 전송
  2. xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"): 헤더 타입을 json으로 설정하여 json 형태로 데이터를 전송
  3. if (resp === "success"): 반환받은 결과값이 "success"라면 회원가입을 완료시킨 후 메인페이지로 이동
  4. xhr.send(JSON.stringify(data)): 회원정보가 담긴 data 변수를 JSON 형태로 변환하여 ajax 전송

5. sql-user.xml 작성

<insert id="insertUser" parameterType="board.vo.UserVo">
        <![CDATA[
            INSERT INTO user
                (
                     name,
                     username,
                     password,
                     email,
                     nickname,
                     join_date,
                     oauth
                 )
            VALUES
                (
                     #{name},
                     #{username},
                     #{password},
                     #{email},
                     #{nickname},
                     now(),
                     #{oauth}
                 )
        ]]>
    </insert>

 

프로젝트 전체 코드 Github 주소

https://github.com/sungwoo-jo/Staffriends-Project

 

GitHub - sungwoo-jo/Staffriends-Project: AI 스마트 시각장애인 지팡이

AI 스마트 시각장애인 지팡이. Contribute to sungwoo-jo/Staffriends-Project development by creating an account on GitHub.

github.com

 

728x90