📗 스프링 Spring

[스프링/Spring] Spring MVC 유효성 검사

핑크빛연어 2021. 5. 17. 15:13

 

Spring MVC 유효성 검사

 

사용자 입력에 대해 유효성 검사를 JavaScript 에서 브라우저가 서버로 요청을 보낼 때 먼저 확인하는 경우도 있으나
Spring MVC 를 이용하여 처리하는 경우도 있습니다.

Spring MVC 에서 유효성 검사를 하는 경우에는 
Bean 에 데이터가 입력될 때 어떤 검사를 할 것인지 어노테이션으로 지정하고, 
지정된 어노테이션의 조건에 맞지 않으면 개발자에게 입력값에 오류가 있다는 정보를 전달합니다.

SpringMVC 에서 JSR-303, JSR-380 이라는 규격의 유효성 검사 라이브러리를 사용할 수 있습니다.

 

작성한 파일 목록 입니다.

1. pom.xml
2. Bear29DataBean1.java
3. Bear29Controller.java
4. input_data.jsp
5. input_success.jsp

 

 

1. pom.xml

 

JSR-303 을 사용하려면 javax.validation 라이브러리를 사용하고, 실제 유효성 검사를 할 클래스 코드가 구현된 org.hibernate.validator 라이브러리를 사용합니다.

pom.xml 에 해당 라이브러리의 의존성을 추가합니다.

https://mvnrepository.com/

 

 

<!-- 라이브러리 셋팅 -->
	<dependencies>
		
        ...
        
		<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>2.0.1.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
		<dependency>
			<groupId>org.hibernate.validator</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>6.2.0.Final</version>
		</dependency>

	</dependencies>

 

 

2. Bear29DataBean1.java

 

Bean 에 어노테이션을 설정합니다.
JSR-303과 Hibernate 에서는 다양한 어노테이션을 제공합니다.

여기에서는 @Size(min=2, max=10) 을 이용하여 data1의 글자수가 2~10의 문자열로 설정하였습니다.
@Max(100) 을 이용하여 data2의 숫자가 100이하의 정수값으로 설정하였습니다.

package com.my.spring.beans;

import javax.validation.constraints.Max;
import javax.validation.constraints.Size;

public class Bear29DataBean1 {

	@Size(min=2, max=10)
	private String data1;
	
	@Max(100)
	private int data2;
	
	public String getData1() {
		return data1;
	}
	public void setData1(String data1) {
		this.data1 = data1;
	}
	public int getData2() {
		return data2;
	}
	public void setData2(int data2) {
		this.data2 = data2;
	}
	
}

 

 

3. Bear29Controller.java

 

@Valid 어노테이션 을 설정하여 유효성 검사를 실시할 수 있습니다. 매개변수에 @Valid 어노테이션을 붙여주면 설정해준 Bean 클래스에서 조건 어노테이션에 맞게 유효성 검사를 진행합니다.

BindingResult 객체를 주입받아 유효성 검사 결과를 확인할 수 있습니다. 이 객체에는 유효성 검사에 위배된 정보들이 들어가 있습니다. Request 영역에 errors 라는 이름으로 넘겨질 수 있습니다.

 

package com.my.spring.controller;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.my.spring.beans.Bear29DataBean1;

@Controller
@RequestMapping("/bear29")
public class Bear29Controller {
	
	private String TAG = "===== "+Bear29Controller.class.getSimpleName()+" >> ";
	
	@GetMapping("/input_data")
	public String input_data() {
		System.out.printf(TAG+"input_data() ");
		return "bear29/input_data";
	}
	
	@PostMapping("input_pro")
	public String imput_pro(@Valid Bear29DataBean1 dataBean1,BindingResult result) {
		//유효성 검사 결과가 담겨져 있는 객체 BindingResult 
		System.out.printf(TAG+"imput_pro() - data1 : %s\n", dataBean1.getData1());
		System.out.printf(TAG+"imput_pro() - data2 : %s\n", dataBean1.getData2());
		System.out.printf(TAG+"imput_pro() - result : %s\n", result);
		
		
		//유효성 검사에서 위반된 부분이 있는지 체크 
		if(result.hasErrors()) {
			//유효성 위반 결과를 모두 가져온다
			for(ObjectError obj : result.getAllErrors()) {
				System.out.printf(TAG+"imput_pro() - ObjectError [메세지] : %s\n", obj.getDefaultMessage());
				System.out.printf(TAG+"imput_pro() - ObjectError [code] : %s\n", obj.getCodes());
				System.out.printf(TAG+"imput_pro() - ObjectError [obj name] : %s\n", obj.getObjectName());
				System.out.println(TAG+"imput_pro() - ObjectError --------------------------------------------------");
				
				String[] codes = obj.getCodes();
				for(String c1 : codes) {
					System.out.printf(TAG+"imput_pro() - ObjectError [c1] : %s\n", c1);
				}
				
				if(codes[0].equals("Size.bear29DataBean1.data1")) {
					System.out.println("data1은 2 ~ 10글자를 담을 수 있습니다");
				} else if(codes[0].equals("Max.bear29DataBean1.data2")){
					System.out.println("data2는 100 이하의 값만 담을 수 있습니다");
				}
				
				System.out.printf(TAG+"imput_pro() - ObjectError -------------------------------------------------- \n");
			}
			return "bear29/input_data";
		}
		
		return "bear29/input_success";
	}
	
}

 

에러종류(어노테이션종류).Bean이름.프로퍼티이름 와 같은 규칙으로 출력되었습니다.

Size.bear29DataBean1.data1
Max.bear29DataBean1.data2

 

출력된 로그 입니다.

===== Bear29Controller >> imput_pro() - data1 : appppppppppppppppp
===== Bear29Controller >> imput_pro() - data2 : 300
===== Bear29Controller >> imput_pro() - result : org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'bear29DataBean1' on field 'data1': rejected value [appppppppppppppppp]; codes [Size.bear29DataBean1.data1,Size.data1,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [bear29DataBean1.data1,data1]; arguments []; default message [data1],10,2]; default message [size must be between 2 and 10]
Field error in object 'bear29DataBean1' on field 'data2': rejected value [300]; codes [Max.bear29DataBean1.data2,Max.data2,Max.int,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [bear29DataBean1.data2,data2]; arguments []; default message [data2],100]; default message [must be less than or equal to 100]
===== Bear29Controller >> imput_pro() - ObjectError [메세지] : size must be between 2 and 10
===== Bear29Controller >> imput_pro() - ObjectError [code] : Size.bear29DataBean1.data1
===== Bear29Controller >> imput_pro() - ObjectError [obj name] : bear29DataBean1
===== Bear29Controller >> imput_pro() - ObjectError --------------------------------------------------
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Size.bear29DataBean1.data1
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Size.data1
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Size.java.lang.String
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Size
data1은 2 ~ 10글자를 담을 수 있습니다
===== Bear29Controller >> imput_pro() - ObjectError ============================== 
===== Bear29Controller >> imput_pro() - ObjectError [메세지] : must be less than or equal to 100
===== Bear29Controller >> imput_pro() - ObjectError [code] : Max.bear29DataBean1.data2
===== Bear29Controller >> imput_pro() - ObjectError [obj name] : bear29DataBean1
===== Bear29Controller >> imput_pro() - ObjectError --------------------------------------------------
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Max.bear29DataBean1.data2
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Max.data2
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Max.int
===== Bear29Controller >> imput_pro() - ObjectError [c1] : Max
data2는 100 이하의 값만 담을 수 있습니다
===== Bear29Controller >> imput_pro() - ObjectError ============================== 

 

 

 

4. input_data.jsp

 

errors 를 가져와서 사용하기 위해 spring 태그 taglib 를 추가하고, 오류 메세지 출력을 위한 조건문 작성을 위해 jstl taglib 도 추가해야 합니다.

<%@ taglib prefix='c' uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix='spring' uri="http://www.springframework.org/tags" %>

<spring:hasBindErrors> 태그의 name 을 Bean 클래스로 설정하여 Bean 클래스의 유효성검사에 error 가 있으면 defaultMessage 를 출력하도록 하였습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix='c' uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix='spring' uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>input_data</h1>
	<form action='input_pro' method='post'>
		data1 : <input type='text' name='data1'/><br/>
		<spring:hasBindErrors name="bear29DataBean1">
			<c:if test="${errors.hasFieldErrors('data1') }">
				${errors.getFieldError('data1').defaultMessage }<br/>
			</c:if>
		</spring:hasBindErrors>
		data2 : <input type='text' name='data2'/><br/>
		<spring:hasBindErrors name="bear29DataBean1">
			<c:if test="${errors.hasFieldErrors('data2') }">
				${errors.getFieldError('data2').defaultMessage }<br/>
			</c:if>
		</spring:hasBindErrors>
		<button type='submit'>확인</button>
	</form>
</body>
</html>

 

 

5. input_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>input_success</h1>
	<h3>data1 : ${bear29DataBean1.data1 }</h3>
	<h3>data2 : ${bear29DataBean1.data2 }</h3>
</body>
</html>

 

 

웹 결과화면

 

 

 

 

728x90
반응형