-
유효성 검사웹페이지 제작을 위한 스프링공부 2020. 5. 10. 19:26
유효성 검사
웹 어플리케이션에서 사용자 입력에 대해 유효성을 검사해야 하는 경우가 있습니다.(회원가입 작성내용 규칙확인,글작성 작성내용 규칙 확인)
javascript로 처리할 수도 있지만 spring mvc를 이용하여 처리할 수도 있습니다.
javascript 로 처리
클라이언트 브라우저에서 서버로 요청을 발생하기 전에 확인을 하겠다는 의미
spring mvc에서 처리
클라이언트가 전달한 데이터를 서버에서 확인하고 그것을 저장할지 말지를 결정
JSR -303
spring mvc는 JSR-303규격의 유효성 검사 라이브러리를 사용할 수 있습니다
Bean에 데이터가 입력될 때 어떤 검사를 할 것인지 어노테이션으로 지정하고 지정된 어노테이션의 조건에 맞지 않으면 개발자에게 입력값에 오류가 있다는 정보를 전달합니다
->개발자가 정의한 bean에 일단 값은 주입이 됩니다 들어간 값을 검사해서 규칙에 올바르게 들어왔음과 그렇지 않음을 개발자에게 전달
개발자는 이를 통해 유효성 검사를 진행할 수 있습니다.
JSR-303을 사용하려면 라이브러리를 추가해야 합니다. JSR-303은 실제 유효성 검사를 할 클래스가 존재해야 하는데 여기서는 hibernate(실제로 입력한 데이터(변수에 주입된 값)을 검사하는 검사기)라는 라이브러리를 사용하겠습니다.
javax validation
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency>
hibernate
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.2.Final</version> </dependency>
Bean에 어노테이션 설정
먼저 Bean에 어노테이션을 설정합니다 JSR-303과 Hibernate에서는 다양한 어노테이션을 제공하고 있습니다.
@Size(min = 2,max=10)
private String data1;
->이 변수에 들어올 수 있는값이 최소 2글자에서 최대 10글자 (값이 들어가긴 하지만 잘못됬다라는 정보가 같이 나옴
@Max(100)
private int data2;
->변수에 최대 100까지 들어갈 수 있음
package kr.co.softcampus.beans; import javax.validation.constraints.Max; import javax.validation.constraints.Size; public class DataBean1 { @Max(100) private int data1; @Size(min=2,max=10) private String data2; public int getData1() { return data1; } public void setData1(int data1) { this.data1 = data1; } public String getData2() { return data2; } public void setData2(String data2) { this.data2 = data2; } }
@Valid
Controller의 메서드에서 주입 받는 Bean에 @Valid를 설정하면 유효성 검사를 실시합니다.
유효성 검사 결과를 사용하고자 한다면 BindingResult 객체를 주입받아야하 합니다.
이 객체에는 유효성 검사를 실행한 결과 정보가 담겨있습니다.
이를 통해 Controller에서 사용자가 입력한 값에 문제가 있는지 파악할 수 있습니다.
ex)public String input_pro(@Valid DataBean1 dataBean1,BindingResult result)
package kr.co.softcampus.controller; import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import kr.co.softcampus.beans.DataBean1; @Controller public class TestController { @GetMapping("/input_data") public String input_data() { return "input_data"; } @PostMapping("/input_pro") public String input_pro(@Valid DataBean1 dataBean1,BindingResult result) { System.out.println(dataBean1.getData1()); System.out.println(dataBean1.getData2()); System.out.println(result); return "input_success"; } }
유효성결과를 출력해보겠습니다 입력할때 data1은 유효성 오류를 입력할것이고 data2는 올바르게 입력하겠다
data1에는 111 data2는 aaa를 입력해보았다
결과창
111 aaa org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'dataBean1' on field 'data1': rejected value [111]; codes [Max.dataBean1.data1,Max.data1,Max.int,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBean1.data1,data1]; arguments []; default message [data1],100]; default message [100 이하여야 합니다]
1 errors가 발생했고 data1에 에러가 발생했다는것을 볼 수 있다
위 에러를 ObjectError객체를 사용하여 정리하여 출력해보겠다
package kr.co.softcampus.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 kr.co.softcampus.beans.DataBean1; @Controller public class TestController { @GetMapping("/input_data") public String input_data() { return "input_data"; } @PostMapping("/input_pro") public String input_pro(@Valid DataBean1 dataBean1,BindingResult result) { System.out.println(dataBean1.getData1()); System.out.println(dataBean1.getData2()); //유효성 검사에서 위반된 부분이 있다면.. if(result.hasErrors()) {//true면 유효성 위반 false면 유효성 위반x //유효성 위반 결과를 모두 가져온다. for(ObjectError obj:result.getAllErrors()) {//에러에 대한 정보가 담겨있는 객체가 리스트에 담겨져있음 System.out.println("메시지:"+obj.getDefaultMessage()); System.out.println("code:"+obj.getCode()); System.out.println("object name:"+obj.getObjectName()); System.out.println("-------------------------------------"); } } return "input_success"; } }
결과
올바르지 않게 입력했을때.
111 aaaaaaaaaaaaaa 메시지:크기가 2에서 10 사이여야 합니다 code:Size object name:dataBean1 ------------------------------------- 메시지:100 이하여야 합니다 code:Max object name:dataBean1 -------------------------------------
에러 내용이 모두 출력됨
올바르게 입력했을때.
23 aa
에러 내용이 없음
문제점
개발자가 사용한 어노테이션 max와 size이 여러개의 변수에 선언되어있으면 어떤 변수가 유효성 검사에서 걸렸는지 알 수 가 없다
Objecterror객체의 getCode는 개발자가 사용한 어노테이션을 출력하지만 getCodes는 어떤 변수에서 에러가 발생했는지도 알려준다.
String [] codes = obj.getCodes(); for(String c1:codes) { System.out.println(c1); }
데이터 값을 둘다 올바르지 않게 입력해보겠다
출력값
Max.dataBean1.data1//어떤 어노테이션의 어떤 bean의 어떤 변수가 에러가 있는지 알려줌 배열[0] Max.data1//변수 배열[1] Max.int//변수 타입[2] Max//어노테이션[3] Size.dataBean1.data2 Size.data2 Size.java.lang.String Size
데이터 값을 둘다 올바르게 입력했을때
1 aaa
위를 봤을때 codes의 0번째 배열에 값이 Max.dataBean1.data1 ,Size.dataBean1.data2 이렇게 들어가 있으면 에러가 발생한 것이다 이때 에러내용을 출력해보자
if(codes[0].equals("Max.dataBean1.data1")){ System.out.println("data2는 100이하의 값만 담을 수 있습니다."); }else if(codes[0].equals("Size.dataBean1.data2")) { System.out.println("data1은 2~10글자를 담을 수 있다."); }
총 정리
package kr.co.softcampus.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 kr.co.softcampus.beans.DataBean1; @Controller public class TestController { @GetMapping("/input_data") public String input_data() { return "input_data"; } @PostMapping("/input_pro") public String input_pro(@Valid DataBean1 dataBean1,BindingResult result) { System.out.println(dataBean1.getData1()); System.out.println(dataBean1.getData2()); //유효성 검사에서 위반된 부분이 있다면.. if(result.hasErrors()) {//true면 유효성 위반 false면 유효성 위반x //유효성 위반 결과를 모두 가져온다. for(ObjectError obj:result.getAllErrors()) {//에러에 대한 정보가 담겨있는 객체가 리스트에 담겨져있음 /* * System.out.println("메시지:"+obj.getDefaultMessage()); * System.out.println("code:"+obj.getCode()); * System.out.println("object name:"+obj.getObjectName()); * System.out.println("-------------------------------------"); */ String [] codes = obj.getCodes(); for(String c1:codes) { System.out.println(c1); } if(codes[0].equals("Max.dataBean1.data1")){ System.out.println("data2는 100이하의 값만 담을 수 있습니다."); }else if(codes[0].equals("Size.dataBean1.data2")) { System.out.println("data1은 2~10글자를 담을 수 있다."); } } return "input_data";//에러가 있으면 다시 입력하도록 } return "input_success"; } }
유효성 검사후 jsp에 검사 결과 출력하는방법
<%@ 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> <form action='input_pro' method='post'> data1:<input type='text' name='data1'></br> <spring:hasBindErrors name="dataBean1"> <!-- dataBean1 bean에 유효성 검사에 문제가 있는게 있는가? --> <c:if test="${errors.hasFieldErrors('data1') }"> <!-- data1 프로퍼티에 문제가 있는가 --> ${errors.getFieldError('data1').defaultMessage } <!-- 문제가 있으면 여기에 출력을해라 --> </c:if> </spring:hasBindErrors> data2:<input type='text' name='data2'></br> <spring:hasBindErrors name="dataBean2"> <!-- dataBean1 bean에 유효성 검사에 문제가 있는게 있는가? --> <c:if test="${errors.hasFieldErrors('data2') }"> <!-- data1 프로퍼티에 문제가 있는가 --> ${errors.getFieldError('data2').defaultMessage } <!-- 문제가 있으면 여기에 출력을해라 --> </c:if> </spring:hasBindErrors> <button type="submit">전송</button> </form> </body> </html>
'웹페이지 제작을 위한 스프링공부' 카테고리의 다른 글
JSR-303 (0) 2020.05.12 에러 메시지 커스터마이징 (0) 2020.05.12 message (0) 2020.05.09 properties (0) 2020.05.09 application scope (0) 2020.05.08