본문 바로가기

개발/Spring

Validation 추상화

반응형

Validation
 - 애플리케이션에서 사용하는 객체 검증용 인터페이스 

특징 
 - 어떤 계층과도 관계 없다 > 모든 계층(웹, 서비스, 데이터) 에서 사용해도 좋다.
 - 구현체 중 하나로 .JSR-303(Bean Validation 1.0)과 JSR-349(Bean Validation 1.1)을 지원한다(LocalValidatorFactoryBean)
 - DataBinder에 들어가 바인딩 할 때 같이 사용되기도 한다.

인터페이스
 - booleean supports(Class clazz) : 어떤 타입의 객체를 검증할 때 사용할 것인지 결정함
 - void validate(Object obj, Errors e) : 실제 검증 로직을 이 안에서 구현
     구현할때 ValidationUtils 사용하며 편리함.

1. Validation 사용! - 고대 방법

1-1) Validator 
 - 검증할 값 

package com.bpkim.demospring51;

public class Event {
    Integer id ;

    String title;

    Integer limit;

    String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

 - Validator 

package com.bpkim.demospring51;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class EventValidator implements Validator {

    @Override
    public boolean supports(Class<?> aClass) {
        return Event.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        // 제목이 비어 있으면 에러 표시
        ValidationUtils.rejectIfEmptyOrWhitespace(errors,"title", "notempty", "Empty title is now allowed.");
        
}

 - AppRunner 으로 확인

package com.bpkim.demospring51;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;

import java.util.Arrays;

@Component
public class AppRunner implements ApplicationRunner {

    /* 고전 방식
    * */
    @Override
    public void run(ApplicationArguments args) throws Exception{
        Event event = new Event();
        EventValidator eventValidator = new EventValidator();
        Errors errors = new BeanPropertyBindingResult(event, "event");

        eventValidator.validate(event, errors);
        System.out.println(errors.hasErrors());

        errors.getAllErrors().forEach(e->{
            System.out.println("=== error code ===");
            Arrays.stream(e.getCodes()).forEach(System.out::println);
            System.out.println(e.getDefaultMessage());
        });
    }
}

 

- 실행 
 validator 에서 설정한 notemptyd와 default 메시지 Empty title is now allowed. 가 표시되면서 
  기본으로 다른 메시지도 출력된다.

 

1. 스프링 부트 2.0.5 이상 버전을 사용 할 때 
 - LocationValidatorFactoryBean 빈으로 자동 등록
 - JSR-380(Bean Validation 2.0.1) 구현체로 hibernate-validator 사용.
 - http://beanvalidation.org 

 

Jakarta Bean Validation - Home

Jakarta Bean Validation is a Java specification which lets you express constraints on object models via annotations lets you write custom constraints in an extensible way provides the APIs to validate objects and object graphs provides the APIs to validate

beanvalidation.org

 ** 스프링 2.3.0 이상에서는 다음 의존성을 추가해 주어야 한다.
     그외에는 spring-boot-starter-web 에 추가되어 있다.

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

www.youtube.com/watch?v=cP8TwMV4LjE&t=70s

2. LocationValidatorFactoryBean 사용 - 새로운(?) 방법
 2-1) 
 - 검증할 값 : 어노테이션 사용

package com.bpkim.demospring51;


import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

public class Event {
    Integer id ;

    @NotEmpty
    String title;

    @NotNull @Min(0)
    Integer limit;

    @Email
    String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}


- AppRunner 로 에러 확인 

package com.bpkim.demospring51;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import java.util.Arrays;

@Component
public class App2Runner implements ApplicationRunner {
    /*
        새로운 방식
     */

    // 스프링 부트 2.0.5 이상 이면
    // LocalValidatorFactoryBean이 자동 등록 된다.
    @Autowired
    Validator validator;


    @Override
    public void run(ApplicationArguments args) throws Exception{

        System.out.println(validator.getClass());

        Event event = new Event();
        event.setLimit(-1);
        event.setEmail("eee2");

        Errors errors = new BeanPropertyBindingResult(event, "event");

        validator.validate(event, errors);
        System.out.println(errors.hasErrors());

        errors.getAllErrors().forEach(e->{
            System.out.println("=== error code ===");
            Arrays.stream(e.getCodes()).forEach(System.out::println);
            System.out.println(e.getDefaultMessage());
        });
    }
}

- 실행 결과 확인 
 LocationValidatorFactoryBean을 사용하여 validation 


반응형

'개발 > Spring' 카테고리의 다른 글

데이터 바인딩 추상화 Converter와 Formatter  (0) 2021.04.23
데이터 바인딩 추상화: PropertyEditor  (0) 2021.04.22
Resource 추상화  (0) 2021.04.22
Ioc 컨테이너 - ResourceLoader  (0) 2021.04.22
IoC - ApplicationEventPublisher  (0) 2021.04.11