Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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 JSR-303使用自定义验证器在地图上进行验证_Java_Spring_Bean Validation_Thymeleaf - Fatal编程技术网

Java JSR-303使用自定义验证器在地图上进行验证

Java JSR-303使用自定义验证器在地图上进行验证,java,spring,bean-validation,thymeleaf,Java,Spring,Bean Validation,Thymeleaf,我正在使用Spring和Thymeleaf填写表格: <form method="post" th:action="@{/postForm}" th:object="${myForm}"><!--/* model.addAttribute("myForm", new MyForm()) */--> <input type="text" th:each="id : ${idList}" th:field="*{map['__${id}__']}" />&

我正在使用Spring和Thymeleaf填写表格:

<form method="post" th:action="@{/postForm}" th:object="${myForm}"><!--/* model.addAttribute("myForm", new MyForm()) */-->
    <input type="text" th:each="id : ${idList}" th:field="*{map['__${id}__']}" /><!--/* results in map['P12345'] */-->
</form>
现在,在我的控制器类中,我正在执行以下操作:

@Controller
public class MyController {
    @RequestMapping(value = "/postForm", method = RequestMethod.POST)
    public void postForm(@ModelAttribute @Valid MyForm myForm, BindingResult bindingResult) {
        if (!bindingResult.hasErrors()) {
            // do some stuff
        }
    }
}
但在尝试将
d
放入文本字段以测试验证时,获取
NotReadablePropertyException

java.lang.IllegalStateException: JSR-303 validated property 'map.P12345' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)
Caused by:
org.springframework.beans.NotReadablePropertyException: Invalid property 'map.P12345' of bean class [com.example.form.MyForm]: Bean property 'map.P12345' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:726) ~[spring-beans-4.1.1.RELEASE.jar:4.1.1.RELEASE]
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:717) ~[spring-beans-4.1.1.RELEASE.jar:4.1.1.RELEASE]
    at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99) ~[spring-context-4.1.1.RELEASE.jar:4.1.1.RELEASE]
    at org.springframework.validation.AbstractBindingResult.getRawFieldValue(AbstractBindingResult.java:283) ~[spring-context-4.1.1.RELEASE.jar:4.1.1.RELEASE]
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:143) ~[spring-context-4.1.1.RELEASE.jar:4.1.1.RELEASE]
    ... 84 more
下面是我阅读的示例,并希望使用自定义验证器进行扩展:

编辑: 注释出
@Valid
注释并检查myForm.getMap()包含的内容时,映射已正确填充:

@Controller
public class MyController {
    private final Logger log = LogManager.getLogger(getClass());

    @RequestMapping(value = "/postForm", method = RequestMethod.POST)
    public void postForm(@ModelAttribute /*@Valid*/ MyForm myForm, BindingResult bindingResult) {
        // Output:
        // P12345: d
        // P67890: 
        for (Map.Entry<String, String> entry : myForm.getMap().entrySet()) {
            log.debug(entry.getKey() + ": " + entry.getValue());
        }
    }
}
@控制器
公共类MyController{
私有最终记录器log=LogManager.getLogger(getClass());
@RequestMapping(value=“/postForm”,method=RequestMethod.POST)
公共void postForm(@modeldattribute/*@Valid*/MyForm MyForm,BindingResult){
//输出:
//P12345:d
//P67890:
对于(Map.Entry:myForm.getMap().entrySet()){
log.debug(entry.getKey()+”:“+entry.getValue());
}
}
}

约束验证或上下文假定您正在构建指向对象图中实际可导航属性的路径。Bean验证实际上并不验证这一点,因此理论上您可以添加任何内容,但Spring集成似乎确实使用了该路径。可能需要将错误映射到正确的UI元素(我不知道Spring代码)。您必须做的是确保为正确的节点添加约束冲突。API实际上允许遍历映射。看起来像:

context.buildConstraintViolationWithTemplate( message )
        .addPropertyNode( "foo" )
        .addPropertyNode( null ).inIterable().atKey( "test" )
        .addConstraintViolation();  
在这种情况下,“null”表示映射到键的值。这与向值本身的属性添加冲突形成对比,后者看起来像:

context.buildConstraintViolationWithTemplate( message )
        .addPropertyNode( "foo" )
        .addPropertyNode( "bar" ).inIterable().atKey( "test" )

谢谢!我使用了一个旧的验证api版本(1.0.0.GA,它是hibernate validator 4.2.0的依赖项)。更新它并使用
addPropertyNode(null).inIterable().atKey(字段)工作起来很有魅力。太好了。我想说的是,您应该验证您的验证器/Bean验证版本。这个特定的API可以在Bean验证1.0和1.1之间更改。我给你的例子是基于Bean Validation 1.1的,我不明白这里
null
“bar”
的区别——你介意用OP的例子来解释一下吗?
context.buildConstraintViolationWithTemplate( message )
        .addPropertyNode( "foo" )
        .addPropertyNode( null ).inIterable().atKey( "test" )
        .addConstraintViolation();  
context.buildConstraintViolationWithTemplate( message )
        .addPropertyNode( "foo" )
        .addPropertyNode( "bar" ).inIterable().atKey( "test" )