build.gradle


implementation 'org.springframework.boot:spring-boot-starter-validation'

해당 라인추가하기

 

join.html


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<th:block th:replace="fragment/config :: configFragment" ></th:block>
<head>
    <th:block layout:fragment="css">
        <link rel="stylesheet" th:href="@{/css/styles.css}" >
    </th:block>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Welcome to Chats</title>
</head>
<body>

<header class="welcome-header" id="joinHeader">
    <h1 class="welcome-header__title">Chats 회원가입</h1>
</header>

<form action="/auth/join" id="login-form" th:object="${usersDto}" method="post">
    <input th:field="*{userId}" type="text" placeholder="이메일을 입력해주세요." />
        <span style="color:red; font-weight: bold;" class="err" th:if="${#fields.hasErrors('userId')}" th:errors="*{userId}" />
    <br>

    <input th:field="*{password}" type="password" placeholder="패스워드를 입력해주세요." maxlength="20" />
        <span style="color:red; font-weight: bold;" class="err" th:if="${#fields.hasErrors('password')}" th:errors="*{password}" />
    <br>

    <input th:field="*{handPhoneNo}" type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" placeholder="핸드폰번호를 입력해주세요." maxlength="13" />
        <span style="color:red; font-weight: bold;" class="err" th:if="${#fields.hasErrors('handPhoneNo')}" th:errors="*{handPhoneNo}" />
    <br>

    <input th:field="*{username}" type="text" placeholder="이름을 입력해주세요." />
        <span style="color:red; font-weight: bold;" class="err" th:if="${#fields.hasErrors('username')}" th:errors="*{username}" />
    <br>

    <input type="button" onclick="join()" value="Join" />
</form>

<script
        src="https://kit.fontawesome.com/6478f529f2.js"
        crossorigin="anonymous"
></script>
</body>
</html>

<script th:inline="javascript">

    function join(){
        $("#login-form").submit();
    }

</script>

th:object에 validation이 선언된 객체를 넣고 th:field에 해당 객체의 이름을 넣으면 

id="", name="" 필드가 자동으로 생성됩니다.

 

controller


/**
     * 회원가입 화면
     * @return
     */
    @GetMapping(Url.AUTH.JOIN)
    public String join(Model model){
        model.addAttribute("usersDto", new UsersDto());
        return Url.AUTH.JOIN_HTML;
    }

    /**
     * 회원가입
     * @param usersDto
     * @param result
     * @param session
     * @return
     */
    @PostMapping(Url.AUTH.JOIN)
    public String joinSubmit(@Valid UsersDto usersDto, BindingResult result, HttpSession session){

		//중복체크
        usersDtoValidator.validate(usersDto, result);
        System.out.println(result.getAllErrors());
        if (result.hasErrors()) {
            return Url.AUTH.JOIN_HTML;
        }

        //session 설정
        session.setAttribute("users", usersDto);

        return Url.AUTH.JOIN_CHECK_HTML;
    }

에러가 발생했을경우 join화면으로 return을 하고

발생하지 않을경우 joinCheck 화면으로 return 합니다.

 

UsersDtoValidator.java


package com.chatting.validator;

import com.chatting.dto.UsersDto;
import com.chatting.repository.UsersRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

@Component
@RequiredArgsConstructor
public class UsersDtoValidator implements Validator {

    private final UsersRepository usersRepository;
    @Override
    public boolean supports(Class<?> aClass) {
        return aClass.isAssignableFrom(UsersDto.class);
    }

    @Override
    public void validate(Object object, Errors errors) {
        UsersDto usersDto = (UsersDto) object;
        if(usersRepository.existsByUserIdAndUseYn(usersDto.getUserId(), "Y")){
            errors.rejectValue("userId", "userId",
                    new Object[]{usersDto.getUserId()}, "이미 사용중인 아이디 입니다.");
        }
    }
}

해당 validator는 dto에서 어노테이션으로 벨리데이션을 하지못할경우 만든 custom validator입니다.

 

Users.java


package com.chatting.entity;

import lombok.Builder;
import lombok.Getter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Getter
@Entity
public class Users {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userIdx;

    //사용자 아이디
    private String userId;

    //사용자 패스워드
    private String password;

    //사용자 핸드폰번호
    private String handPhoneNo;

    //사용자 이름
    private String username;

    //사용여부
    private String useYn;

    //푸시토큰
    private String token;

    public Users() {}

    @Builder
    public Users(String userId, String password, String handPhoneNo, String username, String useYn, String token) {
        this.userId = userId;
        this.password = password;
        this.handPhoneNo = handPhoneNo;
        this.username = username;
        this.useYn = useYn;
        this.token = token;
    }

}

 

UsersDto.java


package com.chatting.dto;

import com.chatting.entity.Users;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.Collection;
import java.util.List;

@Getter
@Setter
public class UsersDto implements UserDetails {

    //사용자 아이디
    @NotBlank(message = "아이디는 필수 항목입니다.")
    @Email(message = "이메일 형식이 아닙니다.")
    private String userId;

    //사용자 패스워드
    @NotBlank(message="패스워드는 필수 항목입니다.")
    @Pattern(regexp="(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,20}",
            message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 8자 ~ 20자의 비밀번호여야 합니다.")
    private String password;

    //사용자 핸드폰번호
    @NotBlank(message="핸드폰 번호는 필수 항목입니다.")
    @Pattern(regexp = "[0-9]{10,11}", message = "10~11자리의 숫자만 입력가능합니다")
    private String handPhoneNo;

    //사용자 이름
    @NotBlank(message="이름은 필수 항목입니다.")
    private String username;

    //사용여부
    private String useYn;

    //푸시 토큰
    private String token;

    //권한
    public List<UsersAuthorityDto> authorities;

    public UsersDto() {}

    public UsersDto(String userId, String password, String handPhoneNo, String username, String useYn, String token) {
        this.userId = userId;
        this.password = password;
        this.handPhoneNo = handPhoneNo;
        this.username = username;
        this.useYn = useYn;
        this.token = token;
    }

    // 엔티티변환
    public Users toEntity() {
        return Users.builder()
                .userId(this.userId)
                .password(this.password)
                .handPhoneNo(this.handPhoneNo)
                .userName(this.username)
                .useYn(this.useYn)
                .token(this.token)
                .build();
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

 

UsersRepository.java

import com.chatting.dto.UsersDto;
import com.chatting.entity.Users;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UsersRepository extends CrudRepository<Users, Long> {

    //userId 또는 핸드폰번호로 찾기
    UsersDto findByUserIdOrHandPhoneNoAndUseYn(String userId, String handPhoneNo, String useYn);

    //해당 아이디가 존재하는지 체크
    boolean existsByUserIdAndUseYn(String userId, String useYn);

    //아이디로 검색
    UsersDto findByUserIdAndUseYn(String userId, String useYn);

}

 

blank처리, 이메일, 패스워드 처리를 하였습니다.

 

validation 걸렸을경우

복사했습니다!