prosource

스프링 유효성 검사를 수동으로 트리거하는 방법은 무엇입니까?

probook 2023. 3. 19. 18:20
반응형

스프링 유효성 검사를 수동으로 트리거하는 방법은 무엇입니까?

POJO 필드에 주석이 달린 스프링 검증은 json 요청 본문에서 작성될 때 작동합니다.단, (세터를 사용하여) 같은 오브젝트를 수동으로 작성하고 검증을 트리거하고 싶을 때는 어떻게 해야 할지 모르겠습니다.

개체를 빌드할 수 있는 Builder 내부 클래스가 있는 Registration 클래스가 있습니다.빌드 방식에서는 스프링 검증을 트리거하고 싶습니다.맨 아래로 스크롤하여 Builder를 확인하십시오.build() 및 Builder.valiate() 메서드를 사용하여 현재 구현을 확인합니다.javax.validation을 사용하고 있습니다.검증을 트리거하는 검증자이지만 가능하면 스프링 검증을 활용하는 것이 좋습니다.

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) 

솔루션:

등록 삭제.Builder.validate().등록 갱신.빌더build() 대상:

    public Registration build() {
        Registration entry = new Registration(this);
        return (Registration) ValidatorUtil.validate(entry);
    }

Validation Util.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);
        }
    }
}

Invalid Data Exception.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;
    }
}

Spring은 JSR-303 Bean Validation API를 완전히 지원합니다.여기에는 스프링빈으로서의 JSR-303 구현에 대한 편리한 지원이 포함됩니다.이를 통해 javax.validation을 실행할 수 있습니다.어플리케이션의 검증이 필요한 장소에, 검증기를 삽입할 수 있습니다.

LocalValidatorFactoryBean을 사용하여 기본 JSR-303 Validator를 스프링빈으로 설정합니다.

   <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

위의 기본 설정에서는 기본 부트스트랩메커니즘을 사용하여 JSR-303이 초기화됩니다.클래스 패스에 Hibernate Validator 등의 JSR-303 프로바이더가 존재해야 하며 자동으로 검출됩니다.

5.7.2.1 검증자 주입

LocalValidatorFactoryBean implements both javax.validation.Validator and org.springframework.validation.Validator.검증 로직을 호출해야 하는 콩에 이들 2개의 인터페이스 중 하나의 참조를 삽입할 수 있습니다.

참조를 삽입하다javax.validation.ValidatorJSR-303 API를 직접 사용하는 경우:

// JSR-303 Validator
import javax.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;

}

참조를 삽입하다org.springframework.validation.ValidatorSpring Validation API가 필요한 경우:

// Spring Validator
import org.springframework.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;

}

다음은 JSR 303을 "클래식" 스프링 검증기와 함께 사용하는 좋은 예입니다(Spring Validator Adapter 입력).

이 링크는 매우 도움이 됩니다.javax.validation을 래핑하고 있습니다.org.springframework.validation의 검증자.빈 검증Spring Validator Adapter는 오류에 일관되게 대처하는 데 도움이 되었습니다.제가 받아들일 수 있도록 답변으로 이것을 추가해 주시겠습니까?

그리고의사 선생님도 여기

언급URL : https://stackoverflow.com/questions/28702809/how-to-manually-trigger-spring-validation

반응형