Spring/Maven Project

Spring에 Hibernate(하이버네이트) Validator 적용 - @NotNull, @NotEmpty, @Size, @Valid, BindingResult

carrotweb 2023. 3. 5. 17:15
728x90
반응형

서버에서 유효성 검사를 Controller에서 하지 않고 객체(Bean)에서 유효성 검사를 할 수 있는 빈 유효성 검사(Bean Validation) 구현체에 대해 알아보고 적용하겠습니다.

 

빈 유효성 검사(Bean Validation)는 객체(Bean)를 검증하기 위한 메타데이터(metadata) 모델과 API를 정의한 명세서(Specification)로 Annotation(어노테이션)을 사용하여 메타데이터를 정의하고 유효성을 검증하는 프로세스에 대해 정의되어 있습니다. 그리고 XML Validation Descriptor를 사용하여 메타데이터를 재정의하고 확장할 수 있게 되어 있습니다.

 

이 명세서는 2019년 8월 5일에 Jakarta Bean Validation 2.0 (https://beanvalidation.org/2.0/spec/)으로 릴리즈(배포) 되었습니다.

 

이처럼 Jakarta Bean Validation 2.0 규정에 맞게 동작되도록 구현(implementation)된 것이 Hibernate(하이버네이트) Validator (https://hibernate.org/validator/)입니다.

 

Jakarta Bean Validation 2.0 규정에 맞게 동작되도록 구현된 Hibernate Validator 6.2.x.Final은 Jakarta EE 8(Java EE 8)에서 실행되기 때문에 Java 버전이 8 또는 11, 17 이상 설치되어 있어야 합니다. (2022년 9월 12일 버전은 6.2.5.Final입니다.)

 

그리고 2020년 7월 4일에 Jakarta Bean Validation 3.0 (https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html)이 릴리즈(배포) 되었습니다.

 

Jakarta Bean Validation 3.0 규정에 맞게 동작되도록 구현된 Hibernate Validator 7.0.x.Final은 Jakarta EE 9(Java EE 9)에서 실행되기 때문에 Java 버전이 8 또는 11, 17 이상 설치되어 있어야 합니다. (2022년 8월 3일 버전은 7.0.5.Final입니다.)

 

2022년 9월 9일에는 Hibernate Validator 8.0.0.Final이 릴리즈 되었습니다. Hibernate Validator 8.0.0.Final은 Jakarta EE 10(Java EE 10)에서 실행되기 때문에 Java 버전이 11, 17 이상 설치되어 있어야 합니다.

 

프로젝트가 2022년 7월에 개발자 교육을 위해 만들어졌기 때문에 Hibernate Validator의 버전이 6.2.3.Final입니다. 그래서 최신 버전인 6.2.5.Final이나 7.0.5.Final를 사용하셔도 됩니다.

 

 

Maven Spring Project에 Hibernate Validator 적용하기

 

1. 메이븐 리포지토리(https://mvnrepository.com)에서 "hibernate-validator"으로 검색합니다. 검색된 결과 중에 "org.hibernate.validator > hibernate-validator"인 Hibernate Validator Engine를 선택합니다.

 

2. "Version"중에서 "6.2.3.Final"를 선택합니다. 그리고 [Maven] 탭을 선택하고 복사합니다.

<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.3.Final</version>
</dependency>

 

3. 메이븐 프로젝트에서 pom.xml 파일을 오픈하고 복사한 내용을 붙여 넣기 합니다.

그러면 자동으로  hibernate-validator, jakarta.validation-api, boss-logging, classmate 라이브러리 파일(JAR)들이 다운로드됩니다.

hibernate-validator-6.2.3.Final.jar
jakarta.validation-api-2.0.2.jar
boss-logging-3.4.1.Final.jar
classmate-1.5.1.jar

 

4. WEB-INF/config 폴더에서 dispatcher-servlet.xml 파일을 오픈하여 xmlns:mvc 네임스페이스를 추가하고 <mvc:annotation-driven> 태그를 추가합니다. 만약, 이전에 추가하셨다면 넘어가시면 됩니다.

 

annotation-driven

  • 클래스에 있는 Annotation(어노테이션)들이 동작되도록 처리해 줍니다. 이전에 component-scan를 먼저 선언하였기 MVC 컴포넌트들을 Bean으로 생성하고 처리되는 문제가 없습니다. 만약, component-scan를 하지 않았다면 annotation-driven는 반드시 있어야 합니다. (일반적으로 annotation-driven를 사용하고 패키지에 있는 Bean를 사용하기 위해 component-scan를 사용합니다. 그래서 annotation-driven이 먼저 선언되어 있을 겁니다.)

annotation-driven이 설정되어 있어야 Hibernate Validator에서 유효성 검사에 사용되는 Annotation(어노테이션)들이 처리됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:mvc="http://www.springframework.org/schema/mvc"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
			http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

	<mvc:annotation-driven />
	
	<context:component-scan base-package="com.home.study"/>
	
	<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>

 

 

Hibernate Validator에서 유효성 검사에 사용되는 Annotation(어노테이션)에 대해 알아보겠습니다.

 

NULL 검증

@NotNull : 값이 NULL이 아니어야 합니다.

@Null : 값이 NULL이어야 합니다.

 

문자 검증

@NotEmpty : 값이 공백이 아니어야 합니다. (값이 NULL과 ""이 아니어야 합니다.)

@NotBlank : 값이 공백이 아니어야 합니다. (값이 NULL과 "", " "이 아니어야 합니다.)

 

문자 크기 검증

@Size(min=num, max=num) : 값이 길이가 min보다 크고 max보다 작아야 합니다. (min 이상, max 이하)

 

문자 패턴 검증

@Pattern(regexp=string) : 값이 정규식 패턴과 일치해야 합니다. 

@Email : 값이 이메일 패턴과 일치해야 합니다.

 

참/거짓 검증

@AssertTrue : 값이 true이어야 합니다. 

@AssertFalse : 값이 false이어야 합니다.

 

숫자 검증(최대, 최소)

@Min(num) : 값이 최소 num보다 커야 합니다. (num 이상)

@Max(num) : 값이 최대 num보다 작아야 합니다. (num 이하)

@DecimalMin("numstring") : 값이 최소 num보다 커야 합니다. (num 이상)

@DecimalMax("numstring") : 값이 최대 num보다 작아야 합니다. (num 이하)

 

숫자 검증(양수, 음수)

@Positive : 값이 양수이어야 합니다. (0 초과)

@PositiveOrZero : 값이 0이거나 양수이어야 합니다. (0 이상)

@Negative : 값이 음수이어야 합니다. (0 미만)

@NegativeOrZero : 값이 0이거나 음수이어야 합니다. (0 이하)

 

숫자 자릿수 검증

@Digits(integer=num, fraction=num) : 최대 정수 자릿수는 integer, 최대 소수 자릿수는 fraction이어야 합니다.

 

시간 검증

@Future : 값이 현재 날짜와 시간보다 커야 합니다.

@FutureOrPresent : 값이 현재이거나 현재 날짜와 시간보다 커야 합니다.

@Past : 값이 현재 날짜와 시간보다 작아야 합니다.

@PastOrPresent : 값이 현재이거나 현재 날짜와 시간보다 작아야 합니다.

 

 

Maven Spring Project의 Model Board에 Hibernate Annotation 추가하기

 

1. Java Resource > src/main/java > com.home.study.test1.board.model 패키지에 있는 Board.java 파일 오픈하고 필드에 Annotation(어노테이션)을 추가합니다.

  1. 등록자 아이디는 Null도 공백도 아니어야 하고 최소 2자 이상 최대 20자 이내이어야 합니다.
  2. 게시판 제목은 Null도 공백도 아니어야 합니다.
/**
 * 게시판 제목
 */
@NotNull
@NotEmpty
private String subject = "";

/**
 * 등록자 아이디
 */
@NotNull
@NotEmpty
@Size(min = 2, max = 20)
private String registrationId = "";

@NotEmpty가 Null인지도 검사하기 때문에 @NotNull은 없어도 됩니다. 또한 필드의 값이 초기화되어 있어 Null이 올 수 없는 없습니다. 그렇지만 Controller이나 Board 클래스를 사용하는 곳에서 필드의 값에 Null을 적용할 수 있기 때문에 @NotNull도 사용하도록 하겠습니다.

 

그럼 Hibernate Validator로 유효성 검사를 하게 하는 방법과 유효성 검사 결과를 리턴 받는 방법에 대해 알아보겠습니다.

 

@Valid Annotation

 

Controller에서 Method(메서드) Parameter(파라미터)전달받은 객체에 @Valid Annotation(어노테이션)를 추가하면 Hibernate Validator로 객체(Bean)를 유효성 검사합니다.


BindingResult

 

Hibernate Validator로 유효성 검사한 검사 결과를 가지고 있는 객체입니다.

Method(메서드) Parameter(파라미터) BindingResult를 추가하여 사용하면 됩니다.
BindingResult의 hasErrors() 메서드를 통해 입력 요소에 에러가 있는지 확인할 수 있습니다.

 

 

Maven Spring Project의 Controller BoardController에 @Valid, BindingResult 추가하기

 

1. Java Resource > src/main/java > com.home.study.test.board.controlle 패키지에 있는 BoardController.java 파일 오픈하고 Board 객체에 @Valid 추가하고 BindingResult를 추가합니다.

  1. 유효성 검사를 하기 위해서 @ModelAttribute("board") Board board 앞에 @Valid를 추가합니다.
  2. 유효성 검사 결과를 리턴 받기 위해서 파라미터로 BindingResult bindingResult를 추가합니다.
  3. Bean에 유효성 검사한 검사 결과를 확인하기 위해 bindingResult의 hasErrors() 메서드를 호출합니다.
  4. 유효성 검사한 검사 결과를 Console에 출력되게 처리합니다.
package com.home.study.test1.board.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.home.study.test1.board.model.Board;
import com.home.study.test1.board.service.IBoardService;


@Controller
@RequestMapping("/board")
public class BoardController {

	@Autowired
	IBoardService boardService;

	@RequestMapping(value="/addform", method=RequestMethod.GET)
	public String addBoardForm(HttpServletRequest request, HttpServletResponse response,
			@ModelAttribute("board") Board board, ModelMap model) {
		return "board/boardform";
	}

	@RequestMapping(value="/addboard", method=RequestMethod.POST)
	public String addBoard(HttpServletRequest request, HttpServletResponse response,
			@Valid @ModelAttribute("board") Board board, BindingResult bindingResult, ModelMap model) {
		if (bindingResult.hasErrors()) {
			List<FieldError> fieldsErrors = bindingResult.getFieldErrors();
			for (FieldError fieldError : fieldsErrors) {
				System.out.println(fieldError.getField() + " = " + fieldError.getCode() + " / " + fieldError.getDefaultMessage());
			}
			return "board/boardform";
		}
		
		if (!boardService.insertBoardItem(board)) {
			return "board/boardform";
		}
		
		return "redirect:/index.do";
	}
}

 

 

 

Maven Spring Project를 실행하여 웹 브라우저로 확인하기

 

1. "Servers"탭에서 "Tomcat9"를 선택하고 "start"버튼(start the server)을 클릭하면 Tomcat이 실행됩니다.

 

2. 웹 브라우저에서 "http://localhost:9000/index.do"를 입력하고 등록 버튼을 클릭하여 게시물 입력 폼(/board/addform.do)으로 이동한 후 입력 폼에서 작성자, 제목, 내용에 입력하지 않고 등록 버튼을 클릭합니다.

 

3. Eclipse의 Console를 보면 유효성 검사 결과를 확인할 수 있습니다.

registrationId = Size / 크기가 2에서 20 사이여야 합니다
registrationId = NotEmpty / 비어 있을 수 없습니다
subject = NotEmpty / 비어 있을 수 없습니다

 

그렇지만 Hibernate Validator의 유효성 검사 메시지는 자연스럽지 않습니다. 그래서 @Valid Annotation(어노테이션)에 message를 사용하여 유효성 검사 메시지를 변경하겠습니다.

 

Java Resource > src/main/java > com.home.study.test1.board.model 패키지에 있는 Board.java 파일 오픈하고 필드의 Annotation(어노테이션)에 message를 추가합니다.

/**
 * 게시판 제목
 */
@NotNull(message="게시판 제목을 입력하세요.")
@NotEmpty(message="게시판 제목을 입력하세요.")
private String subject = "";

/**
 * 등록자 아이디
 */
@NotNull(message="작성자 아이디를 입력하세요.")
@NotEmpty(message="작성자 아이디를 입력하세요.")
@Size(min = 2, max = 20, message="작성자 아이디는 최소 2자, 최대 20자 이내로 입력하세요.")
private String registrationId = "";

 

"Tomcat"에서 "stop"버튼(stop the server)을 클릭하여 종료하고 다시 "start"버튼(start the server)을 클릭하면 Tomcat를 실해시 킵니다. 그리고 웹 브라우저에서 다시 등록 버튼을 클릭합니다. 그리고 Eclipse의 Console를 보면 유효성 검사 결과 메시지가 변경된 것을 확인할 수 있습니다.

registrationId = Size / 작성자 아이디는 최소 2자, 최대 20자 이내로 입력하세요.
registrationId = NotEmpty / 작성자 아이디를 입력하세요.
subject = NotEmpty / 게시판 제목을 입력하세요.

 

이처럼 Hibernate Validator를 사용하면 유효성 검사가 적용된 필드들을 한 번에 검사할 수 있어 좋습니다. 이어서 유효성 검사 결과를 리턴 받은 BindingResult 객체를 사용하여 웹 브라우저에 유효성 검사 결과 메시지가 노출되도록 하겠습니다. 

 

 

728x90
반응형