백/Spring, Spring Boot

[Spring] 유효성 검사, 에러 메시지 보여주기 예제 코드 도서 등록 시 에러 메시지

연지양갱 2023. 7. 12. 17:26
728x90
반응형
SMALL

교재

스프링 코딩 공작소

https://thebook.io/080266/0447/

 

스프링 코딩 공작소: 13.1.1 유효성 검사의 유형

더북(TheBook): (주)도서출판 길벗에서 제공하는 IT 도서 열람 서비스입니다.

thebook.io

 


 

유효성 검사(Validation)

프로세스 또는 시스템의 맥락에서 개념이나 구성이 수용 가능한지 확인하는 프로세스

 

 

유효성 검사는

회원가입을 할 때나 공식적인 데이터를 업로드 할 때 등등 다른 데이터와 달라야 한다는 조건을 가지고 있는 데이터를 입력할 때 거의 필수로 가지고 있는 기능입니다. 그 데이터를 구분하기 위해 데이터 저장 전에 검사를 통해서 저장 여부를 확인하는 것입니다. 회원가입할 때 아이디가 다른 사람과 같거나 필수로 작성해야하는 것을 null값으로, 입력을 하지 않았을 때 등 여러 경우를 대비하기 위해 메시지를 보여준다. 시스템이나 웹 애플리케이션 등은 사용자와 소통이 잘 되어야 한다. 어떤 오류인지 어떻게 작성해야하는 지 사용자에게 보여주기 위해서 유효성 검사를 실시하는 것이다.

 

 

즉,

데이터를 데이터베이스에 저장하기 전에 데이터 조건에 부합한지 확인, 검증하는 작업을 말합니다.

 

유효성 검사해야하는 것들 예시

• 입력 데이터가 null인지에 대한 유효성 검사

• 날짜나 이메일을 입력할 때 형식에 맞는지에 대한 유효성 검사

• 나이를 입력할 때 숫자인지에 대한 유효성 검사

• 입력 데이터의 제한 길이를 초과했는지에 대한 유효성 검사

• 로그인 인증을 할 때 아이디와 패스워드에 대한 유효성 검사

• 회원 가입을 할 때 아이디 중복 여부에 대한 유효성 검사

 

 

유효성 검사의 유형

폼 데이터 값의 유효성 검사

  • JSR-380 Validation(Bean Validation)

웹 애플리케이션을 구성하는 특정 도메인 클래스의 멤버 변수, 즉 필드에 대한 유효성 검사 제약 사항(constraints) 애너테이션을 선언하여 해당 값이 올바른지 검증하는 방식

 

 

  • Validator 인터페이스 : 스프링에서 제공

웹 애플리케이션을 구성하는 특정 도메인 클래스의 멤버 변수에는 제약 사항 애너테이션을 선언하지 않습니다. 그 대신 스프링에서 제공하는 Validator 인터페이스로 구현하고 이를 Validator 인스턴스로 사용하여 해당 속성 값의 유효성 검사를 수행합니다. 스프링 Validator 인터페이스는 애플리케이션의 모든 계층에서 유효성 검증을 위해 사용

 

 

 

 


JSR-380으로 유효성 검사

특정 도메인 클래스의 프로퍼티(멤버 변수), 필드에 대해 유효성 검사의 제약 사항 애너테이션을 선언하여 해당 멤버 변수 값이 올바른지 검사하는 것이다. Bean Validation 2.0이라고도 부릅니다.

 

Bean Validation은 JavaBean 유효성 검증을 위한 메타데이터 모델과 API에 대한 정의입니다. JavaBean은 직렬화 가능하고 매개변수가 없는 생성자를 갖습니다. 

Getter, Setter 메소드를 사용하여 접근할 수 있습니다.

 

 

JSR-380 애너테이션을 이용하여 웹 애플리케이션을 구성하는 방법

  1. JSR-380 제약 사항의 애너테이션 선언
  2.  @Valid를 이용한 유효성 검사 실행
  3.  <form:errors> 태그로 오류 메시지 출력

 

MVC 설정 파일에서 

annotation-drive요소를 등록해야함

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/mvc
                                 http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <annotation-driven/>
</beans:beans>

 

클래스 양식

public class 클래스 이름 {
    @JSR-380 제약 사항 애너테이션(속성[, message="오류 메시지 또는 [오류 코드]"])
    private String 멤버 변수;
    ...
    // Setter()와 Getter() 메서드 구현 생략
}

 

▼ 표 13-1 JSR-380 애너테이션 유형

유형 설명 속성
@AssertFalse 프로퍼티 값이 거짓(false)인지 검사합니다.  
@AssertTrue 프로퍼티 값이 참(true)인지 검사합니다.  
@DecimalMax 프로퍼티 값이 가질 수 있는 최대 실수 값을 검사합니다. • value: 값
• inclusive: true/false
@DecimalMin 프로퍼티 값이 가질 수 있는 최소 실수 값을 검사합니다. • value: 값
• inclusive: true/false
@Digits 프로퍼티가 가질 수 있는 지정된 범위(정수 부분의 자릿수와 소수 부분의 자릿수)를 검사합니다. • integer: 정수의 자릿수
• fraction: 소수의 자릿수
@Future 프로퍼티 값이 미래 날짜(현재일 이후)인지 검사합니다.  
@Max 프로퍼티 값이 가질 수 있는 최대 길이를 검사합니다. value: 값
@Min 프로퍼티 값이 가질 수 있는 최소 길이를 검사합니다. value: 값
@NotNull 프로퍼티 값이 Null이 아닌지 검사합니다.  
@Null 프로퍼티 값이 Null인지 검사합니다.  
@Past 프로퍼티 값이 과거 날짜(현재일 이전)인지 검사합니다.  
@Pattern 프로퍼티 값이 정의된 정규 표현식에 일치하는지 검사합니다. regexp: 정규 표현식
@Size 프로퍼티 값이 가질 수 있는 최대, 최소 길이를 검사합니다. • min: 최소 길이
• max: 최대 길이
@Valid 객체에 대해 유효성 검사를 합니다.

 

JSR-380을 이용하여 유효성 검사 예제 코드

1. pom.xml 파일에 유효성 검사 관련 의존 라이브러리 추가

dependencies 사이에 값을 추가하면됩니다.

 <!-- Validation -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.2.Final</version>
        </dependency>

 

Book.java

package com.springmvc.domain;
...


import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.validation.constraints.Min;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
 

public class Book {
    @Pattern(regexp="ISBN[1-9]+") 
    private String bookId;

    @Size(min=4, max=50) 
    private String name;

    @Min(value=0) 
    @Digits(integer=8, fraction=2) 
    @NotNull 
    private int unitPrice;
    ...
}

@Pattern, @Size, @min, @Digits, @NotNull을 사용하여 오류 조건을 선언해둡니다.

자세한 내용은 위 표를 확인하면 됩니다.

 

 

BookController.java

package com.springmvc.controller;
...
import javax.validation.Valid;
import org.springframework.validation.BindingResult;

@Controller
@RequestMapping("/books")
public class BookController {
    ...

    @PostMapping("/add")
    public String submitAddNewBook(@Valid @ModelAttribute("NewBook") Book book, BindingResult result) { 


        if (result.hasErrors())
            return "addBook";
        }
        MultipartFile bookImage = book.getBookImage();
        String saveName = bookImage.getOriginalFilename();
        File saveFile = new File("C:\\upload", saveName);
    ...
}

@Valid 를 넣어서 오류 내용을 확인합니다. BindingResult result로 오류 내용을 확인하면서 오류가 있다면 addBook을 리턴하여 jsp 파일을 사용자에게 return 합니다.

 

 

addBook.jsp

<%@ page contentType="text/html; charset=utf-8" %>
    ...
    <form:form modelAttribute="NewBook"
               action="./add?${_csrf.parameterName}=${_csrf.token}"
               class="form-horizontal"
               enctype="multipart/form-data">
    <fieldset>
        <legend><spring:message code="addBook.form.title.label"/></legend>
        <div class="form-group row">
            <label class="col-sm-2 control-label">
                <spring:message code="addBook.form.bookId.label"/>
            </label>
            <div class="col-sm-3">
                <form:input path="bookId" class="form-control"/>
            </div>
            <div class="col-sm-6">
                <form:errors path="bookId" cssClass="text-danger"/>
            </div>
        </div>
        <div class="form-group row">
            <label class="col-sm-2 control-label">
                <spring:message code="addBook.form.name.label"/>
            </label>
            <div class="col-sm-3">
                <form:input path="name" class="form-control"/>
            </div>
            <div class="col-sm-6">
                <form:errors path="name" cssClass="text-danger"/>
            </div>
        </div>
        <div class="form-group row">
            <label class="col-sm-2 control-label">
                <spring:message code="addBook.form.unitPrice.label"/>
            </label>
            <div class="col-sm-3">
                <form:input path="unitPrice" class="form-control"/>
            </div>
            <div class="col-sm-6">
                <form:errors path="unitPrice" cssClass="text-danger"/>
            </div>
        </div>
...

modelAttribute="NewBook" 

action="./add?${_csrf.parameterName}=${_csrf.token}"

class="form-horizontal"

enctype="multipart/form-data"

form tag를 이용하여 값을 전송합니다. 요런 태그를 통해서 값을 보냅니다.

 

<form:errors>부분에 오류 메시지가 출력됩니다.

여기에서 path는 값을 유효성 검사를 실행할 부분으로 값을 지정해두는 것을 의미합니다.

 

 

***** properties를 사용함 ******

properties 리소스를 도메인값을 확인하고 오류 메시지를 삽입됩니다. (다국어 처리)

자료 : https://gamza1013.tistory.com/48

 

messages.properties

Pattern.NewBook.bookId = 유효하지 않은 도서ID입니다(숫자로 조합하고 ISBN으로 시작하세요).
Size.NewBook.name = 유효하지 않은 도서명입니다(최소 4자에서 최대 50자까지 입력하세요).
Min.NewBook.unitPrice = 유효하지 않은 가격입니다(0이상의 수를 입력하세요).
Digits.NewBook.unitPrice = 유효하지 않은 가격입니다(소수점 2자리까지, 8자리까지 입력하세요).
NotNull.NewBook.unitPrice = 유효하지 않은 가격입니다(가격을 입력하세요).

=> Patter.NewBook.bookId

JSR-380 애너테이션 이름. 커맨드 객체이름.필드 이름

로  값을 넣어둬두 된다.

 

<form : form> 태그 

modelAttribute="NewBook" // 커맨드 객체이름

 

<form : errors> 태그

path = bookId, name, unitPrice ... // 필드 이름

 

등을 있을 건데 해당 필드의 값을 확인하여 error 메시지를 뷰에서 보여줍니다.

 

 

하단의 @Valid 를 이용한  유효성 검사 부분도 동일하게 properties를 사용했습니다.

 

 

 


 

 

@Valid를 이용하여 유효성 검사

@Valid 애너테이션을 사용하여 유효성 검사, 환경설정과 오류 메시지 출력

 

 

 

pom.xml 의존 라이브러리 등록

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>7.0.4.Final</version>
</dependency>

 

@Valid 선언하기

컨트롤러 내에서 요청 처리 메소드의 매개변수에 전달되는 폼 데이터 값에 대한 유효성 검사를 실행

 

@PostMapping("/...")
public String 메서드 이름(@Valid 매개변수, ..., BindingResult result) {
    if (result.hasErrors()) {
        // 오류 메시지 저장
    }
    return "뷰 이름";
}

 

뷰 페이지에서 오류 메시지 출력

상단에 uri를 추가해주고

오류 메시지를 보여준 부분에 <form:errors> 태그를 삽입하면 됩니다.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
...
<form:errors path="커맨드 객체의 멤버 변수 이름">

 

 

 

@Valid를 이용하여 유효성 검사 예제 코드

Example01Controller.java

package com.springmvc.chap13;
...
@Controller
@RequestMapping("/exam01")
public class Example01Controller {

    @GetMapping
    public String showForm(Model model) {
        model.addAttribute("product", new Product());
        return "webpage13_01";
    }
    @PostMapping
    public String submit(@Valid @ModelAttribute Product product, Errors errors) {

        if (errors.hasErrors())
            return "webpage13_01";

        return "webpage13_result";
    }
}

 

webpage13_01.jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>Validation</title>
</head>
<body>
    <h3>유효성 검사</h3>
    <form:form modelAttribute="product" method="post">
        <p>품명 : <form:input path="name"/> <form:errors path="name"/> 
        <p>가격 : <form:input path="price"/> <form:errors path="price"/> 
        <p><input type="submit" value="확인"/> 
        <input type="reset" value="취소"/>
    </form:form>
</body>
</html>

 


@Valid를 선언하여서 요청 처리 메소드를 불러옵니다.

폼 ㅍ이지에서 입력된 값이 커맨드 객체 product로 매핑될 때 유효성 검사를 진행됩니다.

오류가 발생하면 오류 결과 값은 errors객체에 담기고 뷰 페이지 파일로 return됩니다.

그리고 뷰 페이지에서 <form>태그에 값이 입력됩니다.

유효성을 검사하고 오류가 생기면 오류 메시지를 HTML의 <span>태그로 출력 됩니다.

 

오류 메시지가 출력되었을 때 HTML 태그

<html>
<head>
<title>Validation</title>
</head>
<body>
    <h3>유효성 검사</h3>
    <form id="product" action="/chap13/exam01" method="post">
        <p>품명 : <input id="name" name="name" type="text" value="123"/>
                  <span id="name.errors">4자~10자 이내로 입력해 주세요</span>
        <p>가격 : <input id="price" name="price" type="text" value="-100"/>
                  <span id="price.errors">반드시 0보다 같거나 커야 합니다.</span>
        <p><input type="submit" value="확인"/>
        <input type="reset" value="취소"/>
    </form>
</body>
</html>

<span id="name.errors">~~

<span id="price.errors">~~

가 추가 된 것을 확인할 수 있습니다.

 

 


 

정리 내용으로는 부가 설명을 많이 생략했습니다. 자세한 내용은 상단의 스프링 코딩 공작소 교재 내용이 들어있는 더북에서 하나하나 참고하시면서 읽어보시고 코드 작성해 보시면 쉽게 이해할 수 있을 겁니다. 

 

 

 

참고

유효성 검사 정의 : https://programmingrecoding.tistory.com/33

반응형