gpt4 book ai didi

java - 如何手动触发 Spring 验证?

转载 作者:IT老高 更新时间:2023-10-28 13:52:06 26 4
gpt4 key购买 nike

POJO 字段的带注释的 spring 验证在从 json 请求正文创建时起作用。但是,当我手动(使用 setter)创建同一个对象并想要触发验证时,我不知道该怎么做。

这里是 Registration 类,它有 Builder 内部类,可以构建对象。在构建方法中,我想触发 Spring 验证。请滚动到底部并检查 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()。将 Registryaion.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 Validation API。这包括对将 JSR-303 实现引导为 Spring bean 的便捷支持。这允许在您的应用程序中需要验证的任何地方注入(inject) javax.validation.Validator。

使用 LocalValidatorFactoryBean 将默认的 JSR-303 Validator 配置为 Spring bean:

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

上述基本配置将触发 JSR-303 使用其默认引导机制进行初始化。 JSR-303 提供者,例如 Hibernate Validator,预计会出现在类路径中,并且会被自动检测到。

5.7.2.1 注入(inject) validator

LocalValidatorFactoryBean 实现了 javax.validation.Validator 和 org.springframework.validation.Validator。 您可以将这两个接口(interface)之一的引用注入(inject)到需要调用验证逻辑的 bean 中。

如果您更喜欢直接使用 JSR-303 API,请注入(inject)对 javax.validation.Validator 的引用:

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

@Service
public class MyService {

@Autowired
private Validator validator;

}

如果您的 bean 需要 Spring Validation API,则注入(inject)对 org.springframework.validation.Validator 的引用:

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

@Service
public class MyService {

@Autowired
private Validator validator;

}

这是一个解释清楚的例子 Using JSR 303 with "classic" Spring Validators (enter the SpringValidatorAdapter)

This link is very helpful. Wrapping javax.validation.Validator in org.springframework.validation.beanvalidation.SpringValidatorAdapter helped deal with errors consistently. Can you add this as an answer so that I can accept it

Spring doc here

关于java - 如何手动触发 Spring 验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28702809/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com