회원가입

1. 회원가입 이동처리

1) 링크 수정

  • home.jsp 파일의 링크 수정

<a href="/user/register"><h3 class="box-title">회원가입</h3></a>

  • header.jsp 파일의 링크를 수정

<li role="presentation"><a href="/user/register">회원가입</a></li>

  • 회원 관련 요청을 처리해 줄 Controller를 기본 패키지에 생성하고 member/register 요청을 처리해 줄 메소드를 생성
package com.gmail.hi;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class UserController {
    @RequestMapping(value = "user/register", method = RequestMethod.GET)
    public void register(Model model) {
    }
}
  • views 디렉토리에 user 디렉토리를 생성하고 register.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp"%>
<section class="content">
    <!-- 회원가입 -->
    <form id="registerform" enctype="multipart/form-data" method="post">
        <p align="center">
        <table border="1" width="50%" height="80%" align='center'>
            <tr>
                <td colspan="3" align="center"><h2>회원 가입</h2></td>
            </tr>
            <tr>
                <td rowspan="5" align="center">
                    <p></p> <img id="img" width="100" height="100" border="1" /> <br />
                    <br /> <input type='file' id="image" name="image"
                    accept=".jpg,.jpeg,.gif,.png" /><br />
                </td>
            </tr>
            <tr>
                <td bgcolor="#f5f5f5"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;이메일</font></td>
                <td>&nbsp;&nbsp;&nbsp; <input type="email" name="email"
                    id="email" size="30" maxlength=50 required="required" />
                </td>
            </tr>
            <tr>
                <td bgcolor="#f5f5f5"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;비밀번호</font></td>
                <td>&nbsp;&nbsp;&nbsp; <input type="password" name="pw" id="pw"
                    size="20" required="required" />
                </td>
            </tr>
            <tr>
                <td bgcolor="#f5f5f5"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;비밀번호
                        확인</font></td>
                <td>&nbsp;&nbsp;&nbsp; <input type="password" id="pwconfirm"
                    size="20" required="required" />
                </td>
            </tr>
            <tr>
                <td width="17%" bgcolor="#f5f5f5"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;닉네임</font></td>
                <td>&nbsp;&nbsp;&nbsp; <input type="text" name="nickname"
                    id="nickname" size="20" pattern="([a-z, A-Z, 가힣]){2,}"
                    required="required" title="닉네임은 문자 2자 이상입니다." />
                </td>
            </tr>
            <tr>
                <td align="center" colspan="3">
                    <p></p> <input type="submit" value="회원가입" class="btn btn-warning" />
                    <input type="button" value="메인으로" class="btn btn-success"
                    onclick="javascript:window.location='/'">
                    <p></p>
                </td>
            </tr>
        </table>
    </form>
    <br /> <br />
</section>
<%@include file="../include/footer.jsp"%>

2.이미지 미리보기

  • register.jsp에 이미지 미리보기를 위한 스크립트 추가
<script>
    var filename = ''
    // change 이벤트가 발생하면 readURL 호출
    // change - 내용이 변경되면 호출되는 이벤트
    document.getElementById("image").addEventListener('change', function(e) {
        if (this.files && this.files[0]) {
            filename = this.files[0].name;
            var reader = new FileReader();
            reader.onload = function(e) {
                document.getElementById('img').src = e.target.result;
            }
            reader.readAsDataURL(this.files[0]);
        }
    });
</script>

3. 이메일 중복 검사

  • 기본키의 값을 입력받는 경우 중복체크를 수행해야 함
  • 아이디나 이메일을 기본키로 설정하는 경우 포커스가 없어질 때 이벤트와 ajax를 이용해서 중복체크를 수행
  • 중복체크를 ajax를 이용하지 않게 되면 중복된 데이터를 입력했을 때 결과를 전송 한 후 돌아와야 하므로 이전 데이터를 다시 입력해야 하는 경우도 발생하고 페이지 이동에 따른 과부하가 발생할 가능성이 생김
  • Ajax 나 WebSocket을 이용해서 서버로부터 데이터를 받아와서 출력하는 형식의 웹 애플리케이션을 많이 개발함

  • user.xml 파일에 아이디 중복 체크를 위한 sql을 작성

    <!-- email 중복 검사를 위한 sql -->
    <select id="emailcheck" resultType="java.lang.String" parameterType="java.lang.String">
        select email
        from springuser
        where email = #{email}
    </select>
  • SpringUser 테이블 작업을 위한 UserDao 클래스를 기본 패키지에 dao패키지를 생성하고 아이디 중복 검사를 위한 메소드를 구현
package com.gmail.hi.dao;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
    @Autowired
    private SqlSession sqlSession;

    public String emailcheck(String email) {
        return sqlSession.selectOne("user.emailcheck", email);
    }
}
  • 회원 관련 작업을 처리해주는 메소드의 원형을 소유한 UserService 인터페이스를 기본 패키지 안에 생성하고 아이디 중복 검사를 위한 메소드를 선언
package com.gmail.hi;

public interface UserService {
    public String emailcheck(String email);
}
  • 회원 관련 작업을 처리해주는 메소드를 구현한 UserServiceImpl 클래스를 service 패키지에 만들고 아이디 중복 검사를 위한 메소드를 구현
package com.gmail.hi.service;

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

import com.gmail.hi.UserService;
import com.gmail.hi.dao.UserDao;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public String emailcheck(String email) {
        return userDao.emailcheck(email);
    }
}
  • Controller에서 처리한 결과를 json으로 출력하기 위한 의존성 라이브러리를 pom.xml 파일에 추가
        <!-- Controller에서 json으로 처리  -->    
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.7</version>
        </dependency>

jackson 버전이 안맞아서 아래와 같은 Error 발생한다.
해결방법은 jackson 라이브러리를 최신버전으로 변경하였다 (2.5.4 -> 2.9.7)

org.springframework.beans.BeanInstantiationException: Failed to instantiate 
[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Constructor threw exception; 
nested exception is java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException

java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
  • 클라이언트의 요청을 받아서 결과를 JSON으로 리턴해 줄 수 있는 JSONController 클래스를 생성하고 아이디 중복체크를 처리하기 위한 메소드를 구현
package com.gmail.hi;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JSONController {
    @Autowired
    private UserService userService;

    @RequestMapping(value = "user/emailcheck", method = RequestMethod.GET)
    public Map<String, Object> emailcheck(String email) {
        Map<String, Object> map = new HashMap<String, Object>();
        String result = userService.emailcheck(email);
        map.put("result", result == null);
        return map;
    }
}
  • register.jsp 파일의 이메일 입력란 뒤에 메시지를 출력할 div를 생성

<div id="emailDiv"></div>

  • register.jsp 파일에 아이디 중복 검사를 위한 스크립트 코드를 추가
    var emailcheck = false;
    document.getElementById("email").addEventListener("blur",function() {
                        var addr = "emailcheck";
                        var email = document.getElementById("email").value;
                        $.ajax({url : addr,    data : {'email' : email}, dataType : "json", success : function(data) {
                                        if (data.result == true) {
                                            document.getElementById("emailDiv").innerHTML = "사용 가능한 아이디입니다.";
                                            document.getElementById("emailDiv").style.color = 'blue';
                                            emailcheck = true;
                                        } else {
                                            document.getElementById("emailDiv").innerHTML = "사용 불가능한 아이디입니다.";
                                            document.getElementById("emailDiv").style.color = 'red';
                                            emailcheck = false
                                        }
                                    }
                                });
                    })

4. nickname 중복 검사

  • user.xml 파일에 nickname 중복 체크를 위한 sql 을 작성
    <!-- nickname 중복 검사를 위한 sql -->
    <select id="nicknamecheck" resultType="java.lang.String" parameterType="java.lang.String">
        select nickname
        from springuser
        where nickname = #{nickname}
    </select>
  • UserDao 클래스에 nickname 중복검사 메소드를 구현
    public String nicknamecheck(String nickname) {
        return sqlSession.selectOne("user.nicknamecheck", nickname);
    }
  • UserService 인터페이스에 nickname 중복 검사를 위한 메소드를 선언
    public String nicknamecheck(String nickname);
  • UserServiceImpl 클래스에 nickname 중복검사 메소드를 구현
    @Override
    public String nicknamecheck(String nickname) {
        return userDao.nicknamecheck(nickname);
    }
  • JSONController 클래스에 nickname 중복체크를 처리하기 위한 메소드를 구현
    @RequestMapping(value = "user/nicknamecheck", method = RequestMethod.GET)
    public Map<String, Object> nicknamecheck(@RequestParam("nickname") String nickname) {
        Map<String, Object> map = new HashMap<String, Object>();
        String result = userService.nicknamecheck(nickname);
        map.put("result", result == null);
        return map;
    }
  • register.jsp 파일의 nickname 입력란 뒤에 메시지를 출력할 div를 생성

<div id="nicknameDiv"></div>

  • register.jsp 파일에 아이디 중복 검사를 위한 스크립트 코드를 추가
    var nicknamecheck = false;
    document.getElementById("nickname").addEventListener("focusout",function(){
        var nickname = document.getElementById("nickname").value;
        $.ajax({url : "nicknamecheck", data : {'nickname':nickname}, dataType : "json",    success : function(data) {
                    if (data.result == true) {
                        document.getElementById("nicknameDiv").innerHTML = "사용 가능한 nickname 입니다.";
                        document.getElementById("nicknameDiv").style.color = 'blue';
                        nicknamecheck = true;
                    } else {
                        document.getElementById("nicknameDiv").innerHTML = "사용 불가능한 nickname입니다.";
                        document.getElementById("nicknameDiv").style.color = 'red';
                        nicknamecheck = false
                    }
                }
            });
    })

5. 유효성 검사

  • register.jsp 비밀번호 유효성 검사 내역을 출력할 div를 추가

<div id="pwDiv"></div>

  • register.jsp 파일에 유효성 검사를 위한 스크립트 코드를 추가

    document.getElementById("registerform").addEventListener("submit",function(e){
        if(emailcheck == false){
            document.getElementById("emailDiv").innerHTML = "이메일 중복검사를 수행하세요!!";
            document.getElementById("emailDiv").style.color='red';
            document.getElementById("email").focus();
            e.preventDefault();
            }
        if(nicknamecheck == false){
            document.getElementById("nicknameDiv").innerHTML = "닉네임 중복검사를 수행하세요!!";
            document.getElementById("nicknameDiv").style.color='red';
            document.getElementById("nickname").focus();
            e.preventDefault();
            }
    var pw = document.getElementById("pw").value;
    var pwconfirm = document.getElementById("pwconfirm").value;
        if(pw != pwconfirm){
            document.getElementById("pwDiv").innerHTML = "2개의 비밀번호가 다릅니다!!";
            document.getElementById("pwDiv").style.color='red';
            document.getElementById("pw").focus();
            e.preventDefault();
        }
    var pattern1 = /[0-9]/; // 숫자 var
        pattern2 = /[a-zA-Z]/; // 문자 var
        pattern3 = /[~!@#$%^&*()_+|<>?:{}]/;// 특수문자
        if(!pattern1.test(pw) || !pattern2.test(pw) || !pattern3.test(pw) || pw.length < 8) {
            document.getElementById("pwDiv").innerHTML = "비밀번호는 8자리 이상 문자, 숫자, 특수문자로 구성하여야 합니다.";
            document.getElementById("pw").focus();
            e.preventDefault();
        }
    })

6. 파일 업로드

  • 서버에서의 처리

    • 업로드 폴더 생성
    • 업로드 되는 파일의 고유한 이름 생성
    • 파일을 저장
  • 파일 업로드 처리를 위한 기본 설정

    • commons-fileupload 의존성 추가
    • CommonsMultipartResolver 빈을 추가
    • MultipartFile을 이용해서 파일을 받아서 업로드
  • pom.xml에 commons-fileupload 의존성 추가

        <!--  file upload 의존성 추가  -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
  • servlet-context.xml 파일에 CommonsMultipartResolver 빈 생성 코드 추가
    <beans:bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <beans:property value="10485760" name="maxUploadSize" />
    </beans:bean>

7. 암호화

  • 비밀번호는 암호화 해서 저장하고 비교해야 합니다.

  • 암호화는 많은 자바라이브러리들이 기능을 제공합니다.

  • mavenrespository.com에서 jbcrypt를 검색해서 의존성 추가

<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
  • 암호화

String 변경되서 저장되는 문자열= Bcrypt.hashpw(변경할 문자열, BCrypt.gensalt());

  • 암호화된 데이터 체크

boolean isValemailPassword = BCrypt.checkpw(비교할 문자열1, 비교할 문자열2);

8. 회원가입

  • pom.xml 파일에 파일 업로드와 암호화를 위한 의존성 라이브러리를 추가

  • servlet-context.xml 파일에 파일 업로드 처리를 위한 MultipartResolver 설정을 추가

  • user.xml 파일에 회원가입을 처리해 줄 sql을 생성
    <!-- 회원가입을 처리 해 줄 sql -->
    <insert id="register" parameterType="User">
        insert into springuser(email, pw, nickname, image)
        values(#{email}, #{pw}, #{nickname}, #{image})
    </insert>
  • UserDao 클래스에 회원가입을 처리해 줄 메소드를 생성
    public int register(User user) {
        return sqlSession.insert("user.register", user);
    }
  • 회원가입을 처리하는 UserService 인터페이스에 메소드 선언
    public int register(MultipartHttpServletRequest request);
  • 회원가입을 처리하는 메소드를 UserServiceImpl 클래스에 구현
    @Override
    public int register(MultipartHttpServletRequest request) {
        int result = 0;
        String email = request.getParameter("email");
        String pw = request.getParameter("pw");
        String nickname = request.getParameter("nickname");
        MultipartFile image = request.getFile("image");
        String uploadPath = request.getServletContext().getRealPath("/userimage");
        // 파일 이름 만들기
        UUID uemail = UUID.randomUUID();
        String filename = image.getOriginalFilename();
        User user = new User();
        try {
            if (filename.length() > 0) {
                filename = uemail + "_" + filename;
                // 저장된 파일 경로 만들기
                String filepath = uploadPath + "\\" + filename;
                // 파일 업로드
                File file = new File(filepath);
                image.transferTo(file);
            } else {
                filename = "default.png";
            }
            user.setImage(filename);
            user.setEmail(email);
            user.setPw(BCrypt.hashpw(pw, BCrypt.gensalt(10)));
            user.setNickname(nickname);
            System.out.println(user);
            result = userDao.register(user);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return result;
    }
  • 회원가입을 처리하는 메소드를 UserController에 작성
    @Autowired
    private UserService userService;

    @RequestMapping(value = "user/register", method = RequestMethod.POST)
    public String registerPost(MultipartHttpServletRequest request, RedirectAttributes rttr) {
        int result = userService.register(request);
        System.out.print("result:" + result);
        if (result > 0) {
            rttr.addFlashAttribute("insert", "success");
            return "redirect:/";
        } else {
            return "redirect:register";
        }
    }
  • home.jsp에 회원가입 성공을 알리는 대화상자 출력을 위한 코드 추가
<c:if test="${insert != null }">
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
        $(function() {
            $("#dialog-confirm").dialog({
                resizable : false,
                height : "auto",
                width : 400,
                modal : true,
                buttons : {"닫기" : function() {
                        $(this).dialog("close");
                    },
                }
            });
        });
    </script>
</c:if>
<div id="dialog-confirm" title="회원가입" style="display: none">
    <p>
        <span class="ui-icon ui-icon-alert" style="float: left; margin: 12px 12px 20px 0;"></span> 
        회원가입에 성공하셨습니다.이제 로그인하고 사용하시면 됩니다.
    </p>
</div>
  • webapp 디렉토리에 회원 이미지를 저장할 userimage 디렉토리를 생성 하고 default.png 파일을 만들고 실행

results matching ""

    No results matching ""