# 3.1. Spring의 Validator 인터페이스를 사용하여 유효성 검사 by ys

Spring에는 객체의 유효성을 검사하는 데 사용할 수 있는 `Validator`인터페이스가 있습니다.&#x20;

{% hint style="info" %}
유효성 검사를 하기 위해 Spring은 org.springframework.validation.Validator 인터페이스를 제공하고 있다.
{% endhint %}

`Validator`인터페이스는 `Errors`객체를 사용하여 유효성 검사를 하는 동안 유효성 검사기는 `Errors` 객체에 유효성 검사 실패를 보고 할 수 있도록 합니다.&#x20;

작은 데이터 객체의 다음 예제를 고려하십시오.

```java
public class Person {

    private String name;
    private int age;

    // the usual getters and setters...
}
```

다음 예제는 다음과 같이  `org.springframework.validation.Validator` 인터페이스의 두 가지 메소드를 구현하여 `Person`클래스에 대한 유효성 검증 작동을 제공합니다&#x20;

* `supports(Class)`: 이 `Validator`가, 지정된 `Class`의 인스턴스를 유효성을 검사 할 수 있습니까 ?
* `validate(Object, org.springframework.validation.Errors)`: 지정된 객체를 검증합니다. 검증 에러의 경우는, 지정된 `Errors`객체로 그 객체를 등록 합니다.

`Validator`를 구현하는 것은 매우 간단합니다. 특히 Spring Framework에서도 제공 하는 `ValidationUtils` 도우미 클래스를 알고있을 때 더욱 그렇습니다 . 다음 예제에서는 `Person`인스턴스에 대한 `Validator` 를 구현 합니다.

{% hint style="info" %}
그냥 조건을 인터페이스로 만들어주고 빈 등록 하는 것.&#x20;
{% endhint %}

```java
public class PersonValidator implements Validator {

    /**
     * 이 Validator는 단순히 Person 인스턴스를 유효성검사한다
     */
    public boolean supports(Class clazz) {
        return Person.class.equals(clazz);
    }

    public void validate(Object obj, Errors e) {
        ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
        Person p = (Person) obj;
        if (p.getAge() < 0) {
            e.rejectValue("age", "negativevalue");
        } else if (p.getAge() > 110) {
            e.rejectValue("age", "too.darn.old");
        }
    }
}
```

`ValidationUtils`클래스 의 `static` `rejectIfEmpty(..)`메소드는 `name`속성이 `null`있거나 빈 문자열 이면 거부하는 데 사용됩니다 .  [`ValidationUtils`](https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/javadoc-api/org/springframework/validation/ValidationUtils.html)javadoc을 살펴보면 이전의 표시된 예제 이외에 무엇을 제공 기능을 볼 수 있습니다.

{% hint style="info" %}
ValidationUtils 클래스는 Spring에서 제공하는 유틸 클래스이다.

rejectIfEmpty 메서드는 값이 null이거나 빈값일 경우 에러로 발생하고 ” “(공백) 경우에는 통과한다. rejectIfEmptyOrWhitespace 메서드는  (” “)공백까지 검증한다.
{% endhint %}

하나의 `Validator`클래스를 구현하여 각각의 중첩 된 객체를 풍부한(rich)객체로 검증 할 수는 있지만, 객체의 각 중첩 된 클래스에 대한 유효성 검사 로직을 자체 `Validator`구현에 캡슐화하는 것이 좋습니다 . "풍부한"객체의 간단한 예제는 두 개의 `String` 속성 (이름과 성)과 복합 `Address`객체로 구성된 `Customer`입니다. `Address`객체는 `Customer`객체와 독립적으로 사용될 수 있으므로 별개의 `AddressValidator` 기능이 구현되었습니다. 당신은 당신이 원하는 경우 `CustomerValidator`에 포함 된 로직을 재사용하길 원한다면 붙여 넣기를 복사를 하지않고도 `CustomerValidator`내에 `AddressValidator`를 당신은 의존성 주입 하거나 인스턴스화 해서 사용할 수 있습니다.

```java
public class CustomerValidator implements Validator {

    private final Validator addressValidator;

    public CustomerValidator(Validator addressValidator) {
        if (addressValidator == null) {
            throw new IllegalArgumentException("The supplied [Validator] is " +
                "required and must not be null.");
        }
        if (!addressValidator.supports(Address.class)) {
            throw new IllegalArgumentException("The supplied [Validator] must " +
                "support the validation of [Address] instances.");
        }
        this.addressValidator = addressValidator;
    }

    /**
     * This Validator validates Customer instances, and any subclasses of Customer too
     */
    public boolean supports(Class clazz) {
        return Customer.class.isAssignableFrom(clazz);
    }

    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
        Customer customer = (Customer) target;
        try {
            errors.pushNestedPath("address");
            ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
    }
}
```

유효성 검사 오류는 유효성 검사기에 전달 된 `Errors`객체에 보고됩니다 . Spring Web MVC의 경우 `<spring:bind/>`태그를 사용 하여 오류 메시지를 검사 할 수 있지만 `Errors`객체를 직접 검사 할 수도 있습니다 . [javadoc](https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/javadoc-api/org/springframeworkvalidation/Errors.html) 에서 제공되는 메소드에 대한 자세한 정보는 [javadoc](https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/javadoc-api/org/springframeworkvalidation/Errors.html) 에서 찾을 수 있습니다 .

{% hint style="info" %}
Validator을 이해하기 위해 참고하기 좋은 블로그

: <http://wonwoo.ml/index.php/post/1082>
{% endhint %}
