본문 바로가기
스프링

스프링 시큐리티를 이용한 회원가입과 로그인 4 - 유효성 완료

by 근즈리얼 2021. 10. 3.
728x90

1. 유효성 설명

2. memberFormDto

3. memberController - @valid, BindingResult 활용

4. html 파일 에러처리

 

1. 유효성 설명

유효성을 테스트 하는 방법은 전위와 후위가 있습니다.

 

전위 : 데이터베이스까지 가지 않고 서버측에서 확인하는 방법입니다.

ex) name은 빈 칸일 수 없습니다. , password는 최소 8자 이상입니다.

 

후의 : 데이터베이스에서 데이터의 값이 유효한 값인지를 판단합니다.

ex) email의 값이 중복입니다.

 

저는 이런 유효성을 체크하기 위해 validation이라는 라이브러리를 이용할 생각입니다.

우선 build.gradle에 아래 코드를 추가합니다.

 

2. memberFormDto 
package com.asdanything.ask.dto;

import lombok.Data;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;

@Data
public class MemberFormDto {

    @NotBlank(message = "이름은 필수 입력값입니다.")
    private String name;
    @NotBlank(message = "이메일은 필수 입력 값입니다.")
    @Email(message = "이메일 형식으로 입력해 주세요")
    private String email;
    @NotBlank(message = "비밀번호는 필수 입력 값입니다.")
    private String password;
}

@NotBlank : 값이 빈칸일 수 없게 합니다.

@Email : 이메일 형식으로만 데이터를 받을 수 있습니다.

 

3. memberController - @valid, BindingResult 활용
package com.asdanything.ask.controller;

import com.asdanything.ask.Entity.Member;
import com.asdanything.ask.dto.MemberFormDto;
import com.asdanything.ask.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.validation.Valid;

@Controller
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;
    private final PasswordEncoder passwordEncoder;

    @GetMapping("/members/new")
    public String memberForm(Model model){
        model.addAttribute("memberFormDto",new MemberFormDto());
        return "member/memberForm";
    }

    @PostMapping("/members/new")
    public String memberNew(@Valid MemberFormDto memberFormDto, BindingResult bindingResult, Model model){

        if(bindingResult.hasErrors()){
            return "member/memberForm";
        }

        try{
            Member member = Member.createMember(memberFormDto, passwordEncoder);
            memberService.saveMember(member);

        } catch (IllegalStateException e){
            model.addAttribute("errorMessage",e.getMessage());
            return "member/memberForm";
        }
        return "redirect:/";
    }
}

- postMaipping 부분에서 조금 달라진 부분이 있습니다.

- 데이터를 받는 MemberFormDto앞에 @Valid를 붙임으로써 validation을 사용한다고 알려줄 수 있습니다.

- BindingResult 를 사용하면 MemberFormDto의 내용 중 문제가 발생한 부분의 메세지를 받아옵니다.

- 만약 에러가 존재하면 바로 member/memberForm 페이지로 가면됩니다.

- 에러가 존재하지 않을 경우 후위로 넘어가서 데이터베이스에 저장하고 저장할 때 email이 중복되면 IllegalStateException에러가 발생합니다. 이번에는 그 에러를 담아서 member/memberForm 페이지에 넘어갑니다.

- 모든 과정에서 문제가 없었다면 /페이지로 리다이렉트 합니다.

 

4. html 파일 에러처리
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<style>
    .fieldError{
        color : red;
    }
</style>

<body>
<form action="/members/new" method="post" th:object="${memberFormDto}">
    <div>
        <label th:for="name">이름</label>
        <input type="text" th:field="*{name}" placeholder="이름을 입력하세요">
        <p th:if="${#fields.hasErrors('name')}"
            th:errors="*{name}" class="fieldError">Incorrect data</p>
    </div>
    <div>
        <label th:for="email">이메일</label>
        <input type="email" th:field="*{email}" placeholder="이메일을 입력하세요">
        <p th:if="${#fields.hasErrors('email')}"
           th:errors="*{email}" class="fieldError">Incorrect data</p>
    </div>
    <div>
        <label th:for="password">비밀번호</label>
        <input type="password" th:field="*{password}" placeholder="비밀번호를 입력하세요">
        <p th:if="${#fields.hasErrors('password')}"
           th:errors="*{password}" class="fieldError">Incorrect data</p>
    </div>
    <button type="submit">제출하기</button>
</form>

</body>
</html>

- <p th:if="${#fields.hasErrors('name') th:errors="*{name}" class="fieldError">Incorrect data</p>

- 위의 코드를 살펴보겠습니다.

thymeleaf 를 사용한 코드로 if문에서 만약 에러가 존재하면 <p>~</p>의 내용을 보여줍니다.

- name의 에러가 존재하면 관련된 에러문을 띄어주는 것을 볼 수 있습니다.

 

 화면

- 아무것도 입력하지않고 제출하기를 눌렀을 때 에러문이 뜨는 것을 확인할 수 있습니다.

728x90

댓글