JUMP개발자 2021. 5. 19. 15:20

스프링에서  애플리케이션에서 사용하는 객체들을 검증용 Interface를 제공한다.

-> 모든 계층 (웹, 데이터, 서비스)에서 사용 가능 하다.

-> Validation은 DataBinder에 들어가 바인딩 할 때 같이 사용되기도 한다.

 

Validator Interface를 구현하는 Class는 두 가지 Method를 구현해서 사용한다.

1. supports : parameter로 받은 Instance의 클래스를 검증

2. validate :  실질적인 Validation이 이루어지는 Method 

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) {
        // aClass와 Event가 같은 클래스인지 boolean으로 판단
        return Event.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors,"title", "notempty",
                "empty title is not allowed");

        // ValidationUtils 뿐만 아니라 아래와 같은 로직을 사용할 수도 있다.
        Event event = (Event) o;
        if(event.getTitle() == null) {
            // errors.rejectValue("title", "not empty");

        }
    }
}

Event 클래스 

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;
    }
}

 

@Component
public class AppRunner implements ApplicationRunner {

    //@Autowired
    //Validator eventValidator;

    @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 ============");
            Arrays.stream(e.getCodes()).forEach(System.out::println);
            System.out.println(e.getDefaultMessage());

        });
    }
}

 

최근에는 위와 같이 Validator를 사용하는 방법 보다는 LocalValidatorFactoryBean을 이용한 Validation 방법을 더 많이 사용한다. 스프링부트 2.3.0부터는 starter-validation을 추가로 설정해줘야 한다.

 

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;
    }
}

Event 클래스에 위와 같이 Validation 어노테이션을 추가합니다.

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    Validator eventValidator;

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

        Event event = new Event();
        event.setLimit(-1);
        event.setEmail("jump");
        //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 ============");
            Arrays.stream(e.getCodes()).forEach(System.out::println);
            System.out.println(e.getDefaultMessage());

        });
    }

}

결과