当前位置: 首页 > 面试题库 >

如何手动触发弹簧验证?

华化
2023-03-14
问题内容

从JSON请求主体创建POJO时,对POJO字段进行注释的Spring验证会起作用。但是,当我手动(使用设置器)创建同一对象并想要触发验证时,我不确定该怎么做。

这是Registration类,它具有可以构建对象的Builder内部类。在构建方法中,我想触发弹簧验证。请滚动到底部并检查Builder.build()和Builder.valiate()方法以查看当前的实现。我正在使用javax.validation.Validator触发验证,但如果可能的话,我更喜欢利用spring验证。

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)

解:

删除了Registraion.Builder.validate()。将Registraion.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;
    }
}

问题答案:

Spring提供了对JSR-303 Bean验证API的全面支持。这包括对将JSR-303实现作为Spring
bean引导的便捷支持。这允许将javax.validation.Validator注入到应用程序中需要验证的任何地方。

使用LocalValidatorFactoryBean将默认的JSR-303验证程序配置为Spring Bean:

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

上面的基本配置将触发JSR-303使用其默认引导机制进行初始化。一个JSR-303提供程序,例如Hibernate
Validator,应该存在于类路径中,并将被自动检测到。

5.7.2.1注入验证器

LocalValidatorFactoryBean implements both javax.validation.Validator and org.springframework.validation.Validator. 您可以将对这两个接口之一的引用注入需要调用验证逻辑的bean中。

javax.validation.Validator如果您希望直接使用JSR-303 API,请插入参考:

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

@Service
public class MyService {

    @Autowired
    private Validator validator;

}

注入对org.springframework.validation.Validator您的bean是否需要Spring Validation API
的引用:

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

@Service
public class MyService {

    @Autowired
    private Validator validator;

}

这是一个充分说明的示例, 将JSR 303与“经典”
Spring验证器一起使用(输入SpringValidatorAdapter)

该链接非常有帮助。在org.springframework.validation.beanvalidation.SpringValidatorAdapter中包装javax.validation.Validator帮助一致地处理错误。您能否将此添加为答案,以便我接受

和 Spring文档在这里



 类似资料:
  • 问题内容: 从JSON请求正文创建POJO字段时,带注释的spring验证有效。但是,当我手动(使用设置器)创建同一对象并想要触发验证时,我不确定该怎么做。 这是Registration类,它具有可以构建对象的Builder内部类。在构建方法中,我想触发弹簧验证。请滚动到底部并检查Builder.build()和Builder.valiate()方法以查看当前的实现。我正在使用javax.vali

  • 当POJO的字段从json请求体创建时,它的注释Spring验证工作。但是,当我手动(使用setters)创建相同的对象并希望触发验证时,我不确定如何做到这一点。 下面是注册类,它具有可以构建对象的生成器内部类。在构建方法中,我想触发spring验证。请滚动到底部并检查生成器。build()和Builder。valiate()方法来查看当前的实现。我在用javax。验证。Validator触发验证

  • 问题内容: 我想手动触发验证,包括使用jQueryValidate显示错误消息。 我要完成的方案是这样的形式: 单击时,仅应进行验证。点击时,仅应进行验证。但是,必须张贴所有字段。我怎样才能做到这一点?我考虑过处理click事件并手动验证表单的一部分。 问题答案: 该库似乎允许验证单个元素。只需将click事件与您的按钮相关联,然后尝试以下操作:

  • 问题内容: 我正在通过日历窗口小部件设置日期时间文本字段值。显然,日历小部件会执行以下操作: 我想要的是:在更改日期时间文本字段中的值时,我需要重置页面中的其他一些字段。我已经将一个onchange事件侦听器添加到了不会被触发的datetimetext字段中,因为我猜只有在元素获得焦点并且其值更改为失去焦点时才会被触发。 因此,我正在寻找一种手动触发此事件的方法(我认为应该注意检查文本字段中的值差

  • 问题内容: 我不喜欢抽象,但 我认为Spring犯了重罪。 但是,如果有人可以解释“自动”配置背后的算法,那么我这次愿意忽略它。 看看spring自己的javadocs,除了说它将智能地猜测您需要的东西以及对条件bean要做的事情之外,它没有什么其他的。 有人知道用于确定需要加载哪些算法的算法吗? 问题答案: 根据我作为Spring Boot用户的经验,Spring Boot决定要启用哪些自动配置

  • 问题内容: 我有一个接口IMenuItem 然后我有一个接口实现 有什么方法可以仅使用IMenuItem接口从配置类创建MenuItem的多个实例?与@autowired之类的?还可以通过指定构造函数的参数来自动装配吗? 问题答案: 实际上对于这种情况是完美的。您可以自动连接特定的类(实现)或使用接口。 考虑以下示例: 现在,您可以根据注释值选择对象的名称,从而选择使用其中一种实现方式 像这样: