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

使用Hibernate Validator(JSR 303)进行跨字段验证

左丘峰
2023-03-14
问题内容

Hibernate Validator 4.x中是否有跨域验证的实现(或第三方实现)?如果没有,实现跨域验证器的最干净方法是什么?

例如,如何使用API​​来验证两个bean属性是否相等(例如,验证密码字段与密码验证字段匹配)。

在注解中,我期望这样的东西:

public class MyBean {
  @Size(min=6, max=50)
  private String pass;

  @Equals(property="pass")
  private String passVerify;
}

问题答案:

每个字段约束都应由不同的验证者注释处理,换句话说,不建议对一个字段进行其他字段的验证注释检查。跨领域验证应在课程级别进行。另外,JSR-303第2.2节表示同一类型的多个验证的首选方法是通过注释列表。这样可以在每次匹配中指定错误消息。

例如,验证通用格式:

@FieldMatch.List({
        @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"),
        @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must match")
})
public class UserRegistrationForm  {
    @NotNull
    @Size(min=8, max=25)
    private String password;

    @NotNull
    @Size(min=8, max=25)
    private String confirmPassword;

    @NotNull
    @Email
    private String email;

    @NotNull
    @Email
    private String confirmEmail;
}

注释:

package constraints;

import constraints.impl.FieldMatchValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;

/**
 * Validation annotation to validate that 2 fields have the same value.
 * An array of fields and their matching confirmation fields can be supplied.
 *
 * Example, compare 1 pair of fields:
 * @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match")
 * 
 * Example, compare more than 1 pair of fields:
 * @FieldMatch.List({
 *   @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"),
 *   @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must match")})
 */
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
@Documented
public @interface FieldMatch
{
    String message() default "{constraints.fieldmatch}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * @return The first field
     */
    String first();

    /**
     * @return The second field
     */
    String second();

    /**
     * Defines several <code>@FieldMatch</code> annotations on the same element
     *
     * @see FieldMatch
     */
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
            @interface List
    {
        FieldMatch[] value();
    }
}

验证者:

package constraints.impl;

import constraints.FieldMatch;
import org.apache.commons.beanutils.BeanUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object>
{
    private String firstFieldName;
    private String secondFieldName;

    @Override
    public void initialize(final FieldMatch constraintAnnotation)
    {
        firstFieldName = constraintAnnotation.first();
        secondFieldName = constraintAnnotation.second();
    }

    @Override
    public boolean isValid(final Object value, final ConstraintValidatorContext context)
    {
        try
        {
            final Object firstObj = BeanUtils.getProperty(value, firstFieldName);
            final Object secondObj = BeanUtils.getProperty(value, secondFieldName);

            return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
        }
        catch (final Exception ignore)
        {
            // ignore
        }
        return true;
    }
}


 类似资料:
  • 问题内容: 我正在使用此答案中指定的相等性验证表单上的两个字段“ password”和“ confirmPassword” 。以下是 约束描述符(验证器接口)。 以下是 约束验证器 (实现类)。 以下是与JSP页面映射的验证器bean(由标记指定)。 更新 一切正常,并按预期进行验证。剩下的一件事就是在未显示的类上方显示指定的错误消息,即 只有一个问题: 发生验证冲突时如何在JSP页面上显示错误消

  • 问题内容: 我注意到有人问过这个问题,但是没有正确回答。 我有一个数据表,其中有两列 开始日期 和 结束日期 。两者都包含总理字符p:calendar控件。我需要确保每一行中column1中的日期都不晚于column2中的日期。我想将其绑定到JSF验证框架中,但是遇到了麻烦。 我尝试将数据表标记为rowStatePreserved =“ true”,这使我能够获取值,但是还是有些错误,因为当它失败

  • 我如何验证一个列表的值跨字段,其中至少一个单一的值必须设置(不是零) 我需要验证至少有一个字段被输入(例如总数不是零) 我遇到的问题是,当任何一个字段发生更改时,validator::total_cost不会重新评估所有正在验证的字段。 在“任意”输入中键入正确的值需要告诉“所有”其他输入,以便根据新的计算字段重新估价! 任何帮助都将不胜感激。 (我的电视机大得多) 我正在使用的标记 AnyVal

  • 我研究了各种输入验证框架,包括用于JSR303 bean验证的Hibernate Validator impl,以及ESAPI Validator接口及其DefaultValidator实现。 ESAPI输入验证围绕通过ESAPI.properties文件进行的regex模式匹配。 ESAPI路由: esapi.properties: Java班: Hibernate验证器/spring MVC路

  • 我正在使用spring(4.2.0.RELEASE)、hibernate validator(5.2.1.Final)和validation api(1.1.0.Final)对后端应用程序进行JSR验证,配置如下:, 但是没有一个JSR303注释在我的应用程序中工作。 注意:在POJO类上添加了JSR303注释,在服务类(使用POJO)上添加了@Validated注释,还尝试在方法级别添加@Val

  • 问题内容: 有没有一种方法可以在 不使用指令的情况下 以角度验证字段?例如:我想在输入字段上进行以下验证。 如果字段为空,则应显示“字段必须包含值”消息。 如果字段包含字母数字字符,则应显示“字段只能包含数字”。 偶数-给用户的消息“值必须是偶数”。 我想在对JavaScript函数的调用中进行以下验证。 我四处搜寻,发现有一种使用ng-valid和$ error的方法,但是我没有设法使其工作。