스프링 프레임워크/스프링 MVC

# Spring MVC 게시판 예제 07 - 회원 가입 유효성 검사 (Feat. Validation)

edenDev 2023. 2. 23.

본 포스팅의 예제는 STS 또는 Eclipse를 사용하지 않고 Intellij를 통해 구현하고 있습니다.

그래서 기존의 STS(Spring Tool Studio)에서 생성된 Spring 프로젝트의 스프링 관련 설정 파일명과

프로젝트 구조가 약간 다를 수 있습니다.Intellij 스프링 mvc 프로젝트 생성 포스팅을 참고해주시면 감사하겠습니다.


Spring-MVC 기본 개념 및 테스트 예제 관련 포스팅 링크

순서 포스팅 제목
1 Intellij에서 Spring MVC Project 생성하기
2 Spring MVC - MariaDB 연결테스트
3 Spring MVC - Mybatis 설정 및 테스트
4 SpringMVC 구조
5 SpringMVC + Mybatis
6 Spring MVC Controller 작성 연습

 

Spring-MVC 게시판 예제 이전 포스팅 링크

순서 포스팅제목
1 IntelliJ를 이용한 Spring MVC Project 생성 하기
2 Bootstrap AdminLTE Template 적용하기
3 ExceptionResovler : 예외페이지 처리
4 Spring AOP 적용하기
5 회원가입 구현하기
6 회원 유효성 검사 (Feat. JavaScript)

1. Validation 적용하기

Validation 적용을 위해 먼저 라이브러리를 추가해주어야 합니다. pom.xml 에 아래와 같이 내용을 추가해주세요

<!-- ja : Validation -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.2.Final</version>
</dependency>

1.1 Validation 적용을 위한 도메인 계층 수정 

기본패키지/user/domain 패키지 안에 UserVo 클래스의 내용을 아래와 같이 수정해주세요

private int user_no; // 유저 번호

    @NotNull
    @Pattern(regexp = "^(?=.*[a-zA-z])(?=.*[0-9])(?!.*[^a-zA-z0-9]).{5,10}")
    private String user_id; // 유저 아아디

    @NotNull
    @Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,30}$")
    private String user_pw; // 유저 비밀번호

    @NotNull
    @Pattern(regexp = "^[가-힣].{1,10}$")
    private String user_nickname; // 유저 닉네임

    @NotNull
    private String user_image; // 프로필 이미지

    @NotNull
    private String user_gender; // 유저 성별

    @Past
    @NotNull
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private Date user_birth; // 유저 생년월일

    @NotNull
    @Length(max = 13)
    @Pattern(regexp = "^01([0|1|6|7|8|9])-?([0-9]{3,4})-?([0-9]{4})$")
    private String user_phone; // 유저 휴대폰 번호

    @NotNull
    @Pattern(regexp = "^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$")
    private String user_email; // 유저 이메일

    private String user_status; // 유저 상태
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private Date user_join_date; // 유저 가입 일자
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private Date user_last_connection_date; // 최종 로그인 일자
    
    // 생성자, getter, setter, toString 생략

1.2 Validation  에러메세지 출력을 위해 message source Bean 추가하기

web-inf/spring/appServlet 패키지 안에 dispatcher-servlet.xml 파일의 내용에 아래와 같이 추가해주세요

<!-- messageSource -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <beans:property name="basename" value="/WEB-INF/spring/message/message"/>
    <beans:property name="defaultEncoding" value="UTF-8"/>
    <beans:property name="cacheSeconds" value="60"/>
</beans:bean>

web-inf/spring/message 패키지 안에 message_ko.properties 파일을 생성후 아래와 같이 내용을 입력해주세요.

NotNull.userVo.user_id=아이디의 필드값이 빈칸이 될 수 없습니다.
Pattern.userVo.user_id=아이디는 영문자 숫자 각 한글자씩 모두 포함하여 5~10글자 사이로 입력 하여야합니다.

NotNull.userVo.user_pw=비밀번호의 필드값이 빈칸이 될 수 없습니다.
Pattern.userVo.user_pw=패스워드는 영문자 숫자 특수문자 각 한글자씩 모두 포함하여 8~30글자 사이로 입력 하여야합니다.

NotNull.userVo.user_nickname=닉네임의 필드값이 빈칸이 될 수 없습니다.
Pattern.userVo.user_nickname=닉네임은 한글로 1~10글자 사이로 입력 하여야 합니다.

NotNull.userVo.user_gender=성별을 체크하여야 합니다.

NotNull.userVo.user_birth=생년월일을 선택하여 주세요.
Past.userVo.user_birth=생년월일은 현재날짜보다 과거여야 합니다.

NotNull.userVo.user_phone=휴대폰의 필드값이 빈칸이 될 수 없습니다.
Length.userVo.user_phone=휴대폰은 최대13글자까지 입력이 가능합니다.
Pattern.userVo.user_phone=휴대폰은 하이폰을 포함하여 입력하여 주시기 바랍니다.

NotNull.userVo.user_email=이메일의 필드값이 빈칸이 될 수 없습니다.
Pattern.userVo.user_email=이메일의 정규식을 지켜주세요

1.3 Validation  적용을 위한 jsp 파일 작성

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ include file="../include/head.jsp" %>

<html>
<body class="hold-transition skin-green-light sidebar-mini" oncontextmenu="return false" oncopy="return false"
      oncut="return false" onpaste="return false" onselect="return false">

<div class="wrapper">

    <%@ include file="../include/top_menu.jsp" %>

    <%@ include file="../include/left_menu.jsp" %>

    <div class="content-wrapper">
        <section class="content container-fluid">
            <div class="register-box-body">
                <p class="login-box-msg">회원가입 페이지</p>
                <form action="${path}/user/insertUserProcess" id="insertForm" method="post">
                    <div class="row mt-2">
                        <div class="col">
                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="joinIdInput">아이디</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="text" id="joinIdInput" class="form-control" name="user_id"
                                           placeholder="아이디를 입력하세요요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertId"><form:errors path="user_id" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="changePassword">비밀번호</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="password" id="changePassword" class="form-control" name="user_pw"
                                           placeholder="비밀번호를 입력하세요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <div class="col-lg-5" id="alterPassword"><form:errors path="user_pw" id="error_message" /></div>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="confirmPassword">비밀번호 확인</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="password" id="confirmPassword" class="form-control" name="user_pw"
                                           placeholder="비밀번호를 한번 더 입력해주세요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alterPassword2"></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="userNickName">닉네임</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="text" id="userNickName" class="form-control" name="user_nickname"
                                           placeholder="닉네임을 입력해주세요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertNickName"><form:errors path="user_nickname" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="userGender">성별</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <form:radiobutton id="userGender" path="user_gender" value="M"/>남
                                    <form:radiobutton id="userGender" path="user_gender" value="W"/>여
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertGender"><form:errors path="user_gender" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="userBirth">생년월일</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="date" id="userBirth" class="form-control" name="user_birth"
                                           placeholder="생년월일을 선택해주세요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertBirth"><form:errors path="user_birth" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="userPhone">휴대폰번호</label>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="text" id="userPhone" class="form-control" name="user_phone"
                                           placeholder="휴대폰번호를 입력해주세요">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertPhone"><form:errors path="user_phone" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <label for="userEmail">이메일</label>
                                </div>
                            </div>
                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input type="text" id="userEmail" class="form-control" name="user_email"
                                           placeholder="이메일주소를 입력해주세요">
                                </div>
                                <div class="col d-grid">
                                    <button type="button" id="checkEmailButton"
                                            class="btn btn-primary" style="height:36px;" disabled='disabled'>인증번호 발송
                                    </button>
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col" id="alertEmail"><form:errors path="user_email" id="error_message" /></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col bi bi-exclamation-square-fill deepblue">
                                    인증번호 발송은 서버 상황에따라 5초에서 10초정도 시간이 걸릴 수 있습니다.
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <input class="form-control" id="checkEmail" type="text"
                                           placeholder="인증번호를 입력해주세요." aria-label="default input example"
                                           disabled="disabled">
                                </div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5" id="alertCertified"></div>
                            </div>

                            <div class="row mt-1">
                                <div class="col-lg-5">
                                    <a type="button" class="btn btn-default pull-left" href="../main/main">취소</a>
                                    <button type="button" class="btn btn-primary infoModBtn pull-right" id="joinButton">
                                        가입하기
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </section>
    </div>

    <%@ include file="../include/footer.jsp" %>

</div>

<%@ include file="../include/plugin_js.jsp" %>
</body>
</html>

2. 테스트

 

댓글