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 에 해당 라이브러리의 의존성을 추가합니다.
<!-- 라이브러리 셋팅 -->
<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>
웹 결과화면
'📗 스프링 Spring' 카테고리의 다른 글
[스프링/Spring] 예외처리 (0) | 2021.05.18 |
---|---|
[스프링/Spring] Interceptor (0) | 2021.05.17 |
[스프링/Spring] Message (0) | 2021.05.14 |
[스프링/Spring] Properties (0) | 2021.05.14 |
[스프링/Spring] 요청방식 (@RequestMapping / @GetMapping / @PostMapping) (0) | 2021.05.13 |