8장 유효성 검사 기능 알아보기

Peter·2023년 6월 28일
0
post-thumbnail

8-1-1 유효성 검사란?

유효성 검사(validation): 입력 내용이 요건에 만족하는지 타당성을 확인하는 입력 체크

  • 단일 항목 검사
  • 상관 항목 검사(서로 관련이 있는 항목을 함께 체크하는 방법)

두가지로 나뉜다

8-1-2 단일 항목 검사란?

단일 항목 검사: 입력 항목 하나에 대해 설정하는 입력 체크 기능
Form 클래스 등의 필드에 어노테이션을 부여해서 사용한다.

어노테이션기능 설명사용 예
@NotNullnull 값이 아닌 것을 검증합니다.@NotNull
Integer no;
@NotEmpty문자열이 null 혹은 공백문자("")가 아닌 것을 검증한다.@NotEmpty
String name;
@NotBlank문자열이 null 혹은 공백(스페이스나 탭 등)이 아닌 것을 검증한다.@NotBlank
String name;
@Max지정한 숫자 이하인 것을 검증한다.#100 이하인 것을 검증
@Max(100)
Integer price;
@Min지정한 숫자 이상인 것을 검증한다.#10 이상인 것을 검증
@Min(10)
Integer age;
@Size문자열이나 컬렉션(Collection)이 지정한 범위의 크기 내인 것을 검증한다.#요소의 수가 0에서 10의 범위인 것을 검증(문자열은 문자열 길이, 컬렉션은 사이즈)
@Size(min=0, max=10)
List selected;
@AssertTrue값이 true인 것을 검증한다.@AssertTrue
Boolean empty;
@AssertFalse값이 false인 것을 검증한다.@AssertFalse
Boolean empty;
@Pattern지정한 정규 표현과 일치하는 것을 검증한다.#영숫자 검증
@Pattern(regexp="[a-zA-Z0-9]*")
@Range지정한 숫자 범위 안에 있는 것을 검증한다.#1 이상, 10 이하인 것을 검증
@Range(min=1, max=10)
Integer point;
@DecimalMax지정한 숫자 이하인 것을 검증한다.#100.0 이하 검증(소수점 이하를 포함해서 검증할 때는 Max가 아니고 DecimalMax를 사용)
@DecimalMax("100.0")
BigDecimal val;
@DecimalMin지정한 숫자 이상인 것을 검증한다.#10.0 이상 검증(소수점 이하를 포함해서 검증할 때는 Min이 아니라 DecimalMin을 사용)
@DeciamlMin("10.0")
BigDecimal val;
@Digits정수부와 소수부의 자릿수를 검증한다.#정수부가 3, 소수부가 1인 것을 검증
@Digits(integer=3, fraction=1)
BigDecimal val;
@Future미래의 날짜인 것을 검증한다.@Future
Date date;
@Past과거의 날짜인 것을 검증한다.@Past
Date date;
@Valid중첩된 Form을 검증한다.@Valid
SampleForm sampleForm;
@Length문자열 길이가 지정한 범위 안에 있는 것을 검증한다(문자열 전용 Size).@Length(min=0, max=10)
String name;
@Email문자열이 이메일 주소 형식인지 검증한다.@Email
String email;
@CreditCardNumber문자열이 신용카드 번호 형식인지 검증한다.@CreditCardNumber
String card;
@URL문자열이 URL 형식인지 검증한다.@URL
String url;

null 체크 어노테이션
어노테이션null인 경우공백 문자("")인 경우스페이스나 탭인 경우
@NotNull체크 에러허가허가
@NotEmpty체크 에러체크 에러허가
@NotBlank체크 에러체크 에러체크 에러

8-1-3 커스텀 유효성 검사란?

상관 항목 검사: 여러 필드에 대해 혼합해 체크하는 것

상관 항목 검사를 수행하는 두 가지 방법
1. Bean Validation을 사용하는 방법
2. 스프링 프레임워크에서 제공하는 Validator 인터페이스를 구현하는 방법

8-2-1 프로젝트 생성

생략

8-2-2- 애플리케이션 레이어 생성

  1. Form 클래스 생성
package com.example.ch8.form;

import lombok.Data;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotNull;

@Data
public class CalcForm {
    @NotNull(message = "왼쪽: 숫자를 입력해주세요.")
    @Range(min=1, max=10, message = "왼쪽: {min}~{max} 범위의 숫자를 입력해주세요.")
    private Integer leftNum;

    @NotNull(message = "오른쪽: 숫자를 입력해주세요.")
    @Range(min=1, max=10, message = "오른쪽: {min}~{max} 범위의 숫자를 입력해주세요.")
    private Integer rightNum;
    
}
  1. 컨트롤러 생성
package com.example.ch8.controller;

import com.example.ch8.form.CalcForm;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;

@Controller
public class ValidationController {
    
//    form-backing bean 초기화
    @ModelAttribute
    public CalcForm seUpForm() {
        return new CalcForm();
    }
    
//    입력 화면 표시
    @GetMapping("show")
    public String showView(){
        // 반환값으로 뷰 이름을 돌려줌
        return "entry";
    }
    
}
  1. 뷰 생성(입력 화면)
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>입력 화면</title>
</head>
<body>
<form th:action="@{/calc}" method="post" th:object="${calcForm}">
  <div>
    <input type="text" th:field="*{leftNum}">
    +
    <input type="text" th:field="*{rightNum}">
  </div>
  <input type="submit" value="계산">
</form>
</body>
</html>
  
  1. 컨트롤러에 추가
@PostMapping("calc")
    public String confirmView(@Validated CalcForm form, BindingResult bindingResult, Model model){
        // 입력 체크에서 에러가 발생한 경우
        if (bindingResult.hasErrors()){
            // 입력 화면으로
            return "entry";
        }
        
        // 값 더하기
        Integer result = form.getLeftNum() + form.getRightNum();
        
        // Model에 저장
        model.addAttribute("result", result);
        
        // 확인 화면으로
        return "confirm";
    }
  1. 뷰에 추가(입력 화면)
<!--에러 표시-->
<ul th:if="${#fields.hasErrors('*')}">
    <li th:each="err:${#fields.errors('*')}" th:text="${err}"></li>
</ul>
  1. 뷰 생성(확인 화면)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>확인 화면</title>
</head>
<body>
    <h2>계산 결과</h2>
    <h3>[[${calcForm.leftNum}]]+[[${calcForm.rightNum}]]=[[${result}]]</h3>
</body>
</html>

8-3-1 일반적인 메시지 관리

일반적으로 애플리케이션에서 표시하는 메시지는 프로그램과 별도로 관리한다.
메시지를 템플릿에서 분리해 메시지만 프로퍼티 파일로 관리하는 편이 유지 관리가 편리하기 때문

8-3-2 스프링 부트에서 메시지 관리하기

  1. messages.properties 생성
# entry 화면용
title.entry=입력 화면
button.send=계산
# CalcForm용
calcForm.leftNum=왼쪽
calcForm.rightNum=오른쪽
  1. 뷰 수정(입력 화면)
<!DOCTYPE html>
<html xmlns:th ="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="#{title.entry}">제목</title>
</head>
<body>
<form th:action="@{/calc}" method="post" th:object="${calcForm}">
    <div>
        <input type="text" th:field="*{leftNum}">
        +
        <input type="text" th:field="*{rightNum}">
    </div>
    <button type="submit" th:text="#{button.send}"></button>
    <!-- 에러 표시 -->
    <ul th:if="${#fields.hasErrors('*')}">
        <li th:each="err:${#fields.errors('*')}" th:text="${err}"></li>
    </ul>
</form>
</body>
</html>
  1. ValidationMessages.properties 생성
# 단일 항목 검사용 메시지
javax.validation.constraints.NotNull.message={0}: 숫자를 입력해주세요.
org.hibernate.validator.constraints.Range.message={0}: {min}~{max} 범위에서 입력해주세요.
# 형변환 체크용 메시지
typeMismatch.java.lang.Integer={0}은 정수를 입력해주세요.
  1. Form 클래스 수정
@Data
public class CalcForm {
    @NotNull
    @Range(min=1,max=10)
    private Integer leftNum;

    @NotNull
    @Range(min=1,max=10)
    private Integer rightNum;
}

8-4-1 커스텀 유효성 검사기 생성

  1. Validator 인터페이스 작성 절차

Validator 인터페이스를 구현하는 커스텀 유효성 검사기를 만드는 절차는 다음과 같다.
1. 스프링 프레임워크가 제공하는 Validator 인터페이스를 구현하는 커스텀 유효성 검사기를 생성
2. 컨트롤러에 앞에서 만든 커스텀 유효성 검사기를 주입(인젝션)하고 WebDataBinder 인터페이스의 addValidator 메서드로 커스텀 유효성 검사기를 등록하여 스프링 MVC에서 이용할 수 있게 하기

  1. Validator 구현 클래스 생성
package com.example.demo.validator;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.example.demo.form.CalcForm;

@Component
public class CalcValidator implements Validator {
   @Override
   public boolean supports(Class<?> clazz) {
       // 인수로 전달받은 Form이 입력 체크의 대상인지를 논리값으로 돌려줍니다.
       return CalcForm.class.isAssignableFrom(clazz);
   }

   @Override
   public void validate(Object target, Errors errors) {
       // 대상 Form을 취득
       CalcForm form = (CalcForm) target;

       // 값이 입력되어 있는지 판단
       if (form.getLeftNum() != null && form.getRightNum() != null) {
           // 왼쪽 입력값이 홀수이고 오른쪽 입력값이 짝수가 아닌 경우
           if (!((form.getLeftNum() % 2 == 1) && (form.getRightNum() % 2 == 0))) {
               // 에러인 경우에는 인수 Errors 인터페이스의 reject 메서드에
               // 에러 메시지의 키를 지정합니다.
               errors.reject("com.example.demo.validator.CalcValidator.message");
           }
       }
   }
}
  1. messages.properties에 추가
# 커스텀 유효성 검사용
com.example.demo.validator.CalcValidator.message=왼쪽에는 홀수를, 오른쪽에는 짝수를 입력해주세요.

8-4-2 컨트롤러에 커스텀 유효성 검사기 등록

  1. 컨트롤러에 추가

컨트롤러인 ValidationController에 커스텀 유효성 검사기를 추가

/** 주입(인젝션) */
@Autowired
CalcValidator calcValidator;

/** 커스텀 유효성 검사기 등록 */
@InitBinder("calcForm")
public void initBinder(WebDataBinder webDataBinder){
    webDataBinder.addValidators(calcValidator);
}
profile
개발자 지망생. 일단 하고보자

0개의 댓글