获取bean验证失败的字段名

acquire field name of bean validation failure

所以我正在执行 JSR-303 bean 验证的 class 有两个字段,每个字段都应用了相同的模式约束:

@Column(name="test_suite_revision")
@XmlElement(name="test_suite_revision")
@NotNull
@Pattern(regexp = "\d\d-\d\d-\d\d\d\d", message = "value must be of the form xx-xx-xxxx")
private String revisionTestSuite;

@Column(name="test_revision")
@XmlElement(name="test_revision")
@NotNull
@Pattern(regexp = "\d\d-\d\d-\d\d\d\d", message = "value must be of the form xx-xx-xxxx")
private String revisionTest;

重要 - 这个 class 不是 classic Spring MVC webapp 中的表单支持 class 但是位于 Web 服务基础上的实体 class。所以验证是在服务中进行的。

现在使用 Web 服务的 Web 客户端是一个 Spring MVC,并且确实有一个表单支持 bean,该 bean 与 jsp 相关联,可以放置错误消息。

假设用户在两个字段之一中输入了格式不正确的字符串。我可以用这个非常标准的代码片段来捕捉它

    Set<ConstraintViolation<TestCase>> violations = validator.validate( permit);
    if( !violations.isEmpty()) {
        logger.debug( "basic validation FAILED with " + violations.size() + " errors");
        Iterator<ConstraintViolation<TestCase>> iter = violations.iterator();
        while( iter.hasNext()) {
            ConstraintViolation<TestCase> cv = iter.next();
            logger.debug( "invalidValue:" + cv.getInvalidValue());
            logger.debug( "message:" + cv.getMessage());
            ConstraintDescriptor<?> cd = cv.getConstraintDescriptor();
            Map<String, Object> mapp = cd.getAttributes();
            for( String keey : mapp.keySet()) {
                logger.debug("mapp key:" + keey + ":" + mapp.get(keey));
            }

写出来

basic validation FAILED with 1 errors
invalidValue:050607
message:value must be of the form xx-xx-xxxx
mapp key:message:value must be of the form xx-xx-xxxx
mapp key:payload:[Ljava.lang.Class;@1367702
mapp key:flags:[Ljavax.validation.constraints.Pattern$Flag;@bf5210
mapp key:groups:[Ljava.lang.Class;@a49be5
mapp key:regexp:\d\d-\d\d-\d\d\d\d

问题来了:如何找出哪个字段未通过验证?我似乎找不到提取字段名称、"revisionTest" 或 "revisionTestSuite" 的方法 来自 ConstraintViolation 对象或 ConstraintDescritpor 对象。

javax.validation-api 的 1.1.0.Final 版本中新提供的 getValidationAppliesTo() 方法似乎很有前途,但到目前为止,该方法在运行时抛出 AbstractMethodError。呃.

TIA,

仍在学习史蒂夫

参见ConstraintViolation#getPropertyPath方法:

/**
 * @return the property path to the value from {@code rootBean}
 */
Path getPropertyPath();

Path.Node#getName 会给你 属性 名字。对于嵌套 bean 中的字段名称,您已经完成了。