ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유효성 검사
    웹페이지 제작을 위한 스프링공부 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
Designed by Tistory.