[SPRING] 스프링 밸리데이션을 수동으로 트리거하는 방법은 무엇입니까?
SPRING스프링 밸리데이션을 수동으로 트리거하는 방법은 무엇입니까?
POJO의 필드에 대한 주석 된 스프링 유효성 검사는 json 요청 본문에서 생성 될 때 작동합니다. 그러나 setter를 사용하여 동일한 객체를 수동으로 만들고 유효성 검사를 트리거하려는 경우 어떻게해야하는지 잘 모르겠습니다.
다음은 오브젝트를 빌드 할 수있는 빌더 내부 클래스가있는 등록 클래스입니다. 빌드 방법에서는 스프링 유효성 검사를 트리거하고 싶습니다. 맨 아래로 스크롤하여 Builder.build () 및 Builder.valiate () 메소드를 확인하여 현재 구현을 확인하십시오. 유효성 검사를 트리거하기 위해 javax.validation.Validator를 사용하고 있지만 가능한 경우 스프링 유효성 검사를 사용하는 것을 선호합니다.
package com.projcore.dao;
import com.projcore.util.ToString;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Set;
/**
* The data transfer object that contains the information of a Registration
* and validation rules for attributes.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Registration {
private static final Logger LOGGER = LoggerFactory.getLogger(Registration.class);
private String id;
@NotEmpty
@Size(max = 255)
private String messageId;
@NotEmpty
@Size(max = 255)
private String version;
@Size(max = 255)
private String system;
public Registration() {
}
private Registration(Builder builder) {
this.id = builder.id;
this.messageId = builder.messageId;
this.version = builder.version;
this.system = builder.system;
}
public static Builder getBuilder() {
return new Builder();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSystem() {
return system;
}
public void setSystem(String system) {
this.system = system;
}
@Override
public String toString() {
return ToString.create(this);
}
/**
* Builder pattern makes the object easier to construct in one line.
*/
public static class Builder {
private String id;
private String messageId;
private String version;
private String system;
private Builder() {}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder messageId(String messageId) {
this.messageId = messageId;
return this;
}
public Builder version(String version) {
this.version = version;
return this;
}
public Builder system(String system) {
this.system = system;
return this;
}
public Registration build() {
Registration entry = new Registration(this);
// *** Would like to trigger spring validation here ***
Set violations = validate(entry);
if (violations.isEmpty())
return entry;
else
throw new RuntimeException(violations.toString());
}
private Set validate(Registration entry) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Registration>> constraintViolations = validator.validate(entry);
return constraintViolations;
}
}
}
여기 유효성 검사가 정상적으로 작동합니다.
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
Registration create(@RequestBody @Valid Registration registration)
해결책:
Registration.Builder.validate ()를 제거하십시오. 업데이트 된 Registration.Builder.build ()
public Registration build() {
Registration entry = new Registration(this);
return (Registration) ValidatorUtil.validate(entry);
}
ValidationUtil.java
package projcore.util;
import com.ericsson.admcore.error.InvalidDataException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
public class ValidatorUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorUtil.class);
private static final Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator();
private static final SpringValidatorAdapter validator = new SpringValidatorAdapter(javaxValidator);
public static Object validate(Object entry) {
Errors errors = new BeanPropertyBindingResult(entry, entry.getClass().getName());
validator.validate(entry, errors);
if (errors == null || errors.getAllErrors().isEmpty())
return entry;
else {
LOGGER.error(errors.toString());
throw new InvalidDataException(errors.getAllErrors().toString(), errors);
}
}
}
InvalidDataException.java
package projcore.error;
import org.springframework.validation.Errors;
/**
* This exception is thrown when the dao has invalid data.
*/
public class InvalidDataException extends RuntimeException {
private Errors errors;
public InvalidDataException(String msg, Errors errors) {
super(msg);
setErrors(errors);
}
public Errors getErrors() {
return errors;
}
public void setErrors(Errors errors) {
this.errors = errors;
}
}
해결법
-
==============================
1.Spring은 JSR-303 Bean Validation API를 완벽하게 지원한다. 여기에는 JSR-303 구현을 스프링 빈으로 부트 스트랩하는 편리한 지원이 포함됩니다. 이를 통해 응용 프로그램에서 유효성 검사가 필요한 모든 위치에 javax.validation.Validator를 삽입 할 수 있습니다.
Spring은 JSR-303 Bean Validation API를 완벽하게 지원한다. 여기에는 JSR-303 구현을 스프링 빈으로 부트 스트랩하는 편리한 지원이 포함됩니다. 이를 통해 응용 프로그램에서 유효성 검사가 필요한 모든 위치에 javax.validation.Validator를 삽입 할 수 있습니다.
LocalValidatorFactoryBean을 사용하여 기본 JSR-303 검사기를 Spring bean으로 구성하십시오.
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
위의 기본 구성은 기본 부트 스트랩 메커니즘을 사용하여 JSR-303을 초기화하도록 트리거합니다. Hibernate Validator와 같은 JSR-303 제공자는 클래스 경로에 존재할 것으로 예상되며 자동으로 감지됩니다.
5.7.2.1 검사기 주입
LocalValidatorFactoryBean은 javax.validation.Validator와 org.springframework.validation.Validator를 모두 구현합니다. 이 두 인터페이스 중 하나에 대한 참조를 검증 로직을 호출해야하는 bean에 삽입 할 수 있습니다.
JSR-303 API를 직접 사용하려면 javax.validation.Validator에 대한 참조를 주입하십시오.
// JSR-303 Validator import javax.validation.Validator; @Service public class MyService { @Autowired private Validator validator; }
bean이 Spring Validation API를 필요로한다면 org.springframework.validation.Validator에 대한 참조를 주입하십시오 :
// Spring Validator import org.springframework.validation.Validator; @Service public class MyService { @Autowired private Validator validator; }
다음은 잘 설명 된 예제입니다. "클래식"스프링 밸리데이터가있는 JSR 303 사용 (SpringValidatorAdapter 입력)
과 여기 Spring doc
from https://stackoverflow.com/questions/28702809/how-to-manually-trigger-spring-validation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 오류 발생 : JDBC 드라이버 클래스를로드 할 수 없습니다 [org.postgresql.Driver] (0) | 2019.04.16 |
---|---|
[SPRING] Spring에서 문자열 배열을 빈에 삽입 (0) | 2019.04.16 |
[SPRING] Spring : classpath 자원을위한 URL 삽입 (0) | 2019.04.16 |
[SPRING] Spring REST 컨트롤러를 테스트 할 때 @AuthenticationPrincipal 삽입 (0) | 2019.04.16 |
[SPRING] @ComponentScan을 Spring의 테스트 특정 컨텍스트 구성과 함께 사용하는 방법 Junit4 TestRunner? (0) | 2019.04.16 |