Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring验证-避免重复的约束消息_Java_Spring_Validation - Fatal编程技术网

Java Spring验证-避免重复的约束消息

Java Spring验证-避免重复的约束消息,java,spring,validation,Java,Spring,Validation,这里是新的Spring开发者。我已经搜索了SO和spring文档,但没有找到答案 我试图使用Spring验证将任何适用的验证程序实现应用于任意对象,方法是注入所有注册的验证程序,并通过调用supports()对其进行迭代,然后有条件地validate()。这是可行的,只是它会产生重复的验证消息,因为JSR-303约束注释会被验证两次——一次是由jsr303Validator验证,另一次是由mvcValidator验证 我尝试调用所有验证器并在之后删除重复的错误,但是ObjectError上的eq

这里是新的Spring开发者。我已经搜索了SO和spring文档,但没有找到答案

我试图使用Spring验证将任何适用的
验证程序
实现应用于任意对象,方法是注入所有注册的验证程序,并通过调用
supports()
对其进行迭代,然后有条件地
validate()
。这是可行的,只是它会产生重复的验证消息,因为JSR-303约束注释会被验证两次——一次是由
jsr303Validator
验证,另一次是由
mvcValidator
验证

我尝试调用所有验证器并在之后删除重复的错误,但是
ObjectError
上的
equals()
实现没有按预期工作(它会留下带有相同错误代码和消息的条目)

验证程序实现:

import org.springframework.validation.BindException;
import org.springframework.validation.Validator;

@Service
class ObjectValidatorImpl {
    private final Validator[] validators;

    public ObjectValidatorImpl(Validator[] validators) {
        this.validators = validators;
    }

    public void validate(Object obj) throws BindException {
        // Container for holding any validation errors that are found
        BindException errors = new BindException(obj, obj.getClass().getName());

        for (Validator validator : validators) {
            if (validator.supports(obj.getClass())) {
                validator.validate(obj, errors);
            }
        }

        if (errors.hasErrors()) {
            throw errors;
        }
    }
}
显示错误的示例程序:

@SpringBootApplication
public class ValidationTestApplication implements CommandLineRunner {

    @Autowired
    private ObjectValidator objectValidator;

    public static void main(String[] args) {
        SpringApplication.run(ValidationTestApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        try {
            objectValidator.validate(new TestObject());
        }
        catch (BindException ex) {
            System.out.println(ex);
        }
    }
}

class TestObject {
    @NotEmpty
    String name;
}
错误输出示例:

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'validationtest.TestObject' on field 'name': rejected value [null]; codes [NotEmpty.validationtest.TestObject.name,NotEmpty.name,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validationtest.TestObject.name,name]; arguments []; default message [name]]; default message [may not be empty]
Field error in object 'validationtest.TestObject' on field 'name': rejected value [null]; codes [NotEmpty.validationtest.TestObject.name,NotEmpty.name,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validationtest.TestObject.name,name]; arguments []; default message [name]]; default message [may not be empty]
请注意,
jsr303Validator
mvcValidator
都会报告两次“name cannot be empty”错误

渐变依赖项:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-validation')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime("com.h2database:h2")
}

解决这种情况的正确(最灵活的)方法是什么?这感觉像是一个类路径配置问题,我应该避免在同一个项目中使用两个验证器,但这段代码位于共享库中,可能与Spring Web MVC一起使用,也可能与Spring Web MVC不一起使用,我不确定如何防止这种情况发生。

这不是应该发生的吗


您为对象注册了多个验证器,因此当您循环所有验证器并请求验证消息时,您会得到重复的验证器,因为它们都是相似的。

这不是应该发生的事情吗


您为该对象注册了多个验证器,因此当您循环所有验证器并请求验证消息时,您会得到重复的验证器,因为它们都是相似的。

有些代码有助于理解您的问题有些代码有助于理解您的问题可能会发生什么,但这不是我想要的。这个问题可以重新表述为:在使用SpringWeb时,如何避免注册多个JSR303验证器?我没有明确注册验证器,所以我不确定为什么会有两个JSR303验证器,或者如何避免这种情况。这是公平的。你是在自动连接那些验证器吗?它们有不同的用途。我相信mvc将允许将表单绑定到消息。您可以丢弃其中一个验证器,但将来它们可能会做不同的事情(如果其他人添加了自定义验证器)。我认为只要包含
org.springframework.boot:springbootstarterweb
就可以注册MVC验证器。我希望避免硬编码逻辑来排除MVC验证器(例如,通过类名),因为正如您所指出的,这看起来很脆弱。我在寻找一种方法来控制注入的内容或至少运行的内容-基本上我想要标准的JSR303验证器(
LocalValidatorFactoryBean
)和任何特定于应用程序的自定义验证器。我只是不知道如何将注入的验证器列表过滤成这些(或者选择一种更好的方法)。看起来这并不是真的应该发生,但我仍然不明白是谁在设置你的验证器列表。看来你只有通过工厂才能得到一个。如果注册了两个,它应该抛出一个异常。对不起,我没能帮上忙这可能是应该发生的,但这不是我想要发生的。这个问题可以重新表述为:在使用SpringWeb时,如何避免注册多个JSR303验证器?我没有明确注册验证器,所以我不确定为什么会有两个JSR303验证器,或者如何避免这种情况。这是公平的。你是在自动连接那些验证器吗?它们有不同的用途。我相信mvc将允许将表单绑定到消息。您可以丢弃其中一个验证器,但将来它们可能会做不同的事情(如果其他人添加了自定义验证器)。我认为只要包含
org.springframework.boot:springbootstarterweb
就可以注册MVC验证器。我希望避免硬编码逻辑来排除MVC验证器(例如,通过类名),因为正如您所指出的,这看起来很脆弱。我在寻找一种方法来控制注入的内容或至少运行的内容-基本上我想要标准的JSR303验证器(
LocalValidatorFactoryBean
)和任何特定于应用程序的自定义验证器。我只是不知道如何将注入的验证器列表过滤成这些(或者选择一种更好的方法)。看起来这并不是真的应该发生,但我仍然不明白是谁在设置你的验证器列表。看来你只有通过工厂才能得到一个。如果注册了两个,它应该抛出一个异常。对不起,没有更多的帮助