【问题标题】:Spring validation vs Hibernate validation using annotation使用注释的 Spring 验证与 Hibernate 验证
【发布时间】:2011-12-22 07:36:14
【问题描述】:

我正在使用 spring mvc 3.0 创建一个演示应用程序。我必须在屏幕上应用验证。我在网上搜索,发现应用程序主要使用两种类型的验证:-

  1. 使用验证 API 进行春季验证
  2. 使用休眠验证进行休眠验证

希望有人给我建议,哪一个是在应用程序中实现的好。

【问题讨论】:

    标签: spring validation spring-mvc hibernate-validator


    【解决方案1】:

    我两个都用过——我更喜欢 Hibernate Validation——很容易实现而且很标准。当您在类路径上有实现时,它会自动启用。这是一个例子:

    @EmailValidator
    @NotBlank
    @Length(max=65)
    private String email; 
    

    消息错误字符串来自哪里?在 WEB-INF 中,您必须有一个名为 messages.properties 的文件:

    NotBlank.ForgotPasswordBackingObject.email=Email address must be present
    

    有一个标准的@Email 注释,但是诸如:me@mycompany 之类的电子邮件被认为是有效的,这就是为什么我必须制作自己的@EmailValidator(在标准实现中将正则表达式标志从 * 更改为 +)。 我遇到了一些问题:验证的顺序 - 您希望首先进行哪个验证,这是通过验证组完成的,但使用 @Valid 注释是不可能的,例如:

    @RequestMapping(method=RequestMethod.POST, value="/auth/changePassword")
    public ModelAndView submitChangePasswordPage(@Valid @ModelAttribute("ChangePasswordBackingObject") ChangePasswordBackingObject backingObject, BindingResult result, Principal principal)
    

    这就是为什么如果您的控制器采用这种形式(例如在 Spring MVC 中),那么您必须以某种方式模拟您的逻辑 - 我也这样做了。

    你可以做的另一件很酷的事情是一次验证两个或多个字段(我发现这非常有用):

    @FieldMatch.List({
        @FieldMatch(firstValue = "password" , secondValue = "confirmPassword")
    })
    public class RequestAccountBackingObject implements Serializable {
        private String password;
        private String confirmPassword;
    

    以及实现:

    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = FieldMatchImpl.class)
    @Documented
    public @interface FieldMatch{
        String message() default "{com.errorMessage}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
        String firstValue();
        String secondValue();
        @Target({TYPE, ANNOTATION_TYPE})
        @Retention(RUNTIME)
        @Documented
        @interface List
        { FieldMatch[] value(); }
    }
    

    另一个 FieldMatchImpl 是:

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

    你需要实现两个方法:

    public void initialize(final FieldMatch constraintAnnotation){
        firstFieldName = constraintAnnotation.firstValue();
        secondFieldName = constraintAnnotation.secondValue();
    

    还有:

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

    使用 org.apache.commons.beanutils.BeanUtils 您现在可以验证这两个字段。

    像这样:

    boolean result = firstObj.equals(secondObj);
    if(!result) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(errorMessage).addNode(firstFieldName).addConstraintViolation();
    }
    

    除此之外,到目前为止,使用 Hibernate 验证是一种乐趣。

    【讨论】:

    • 感谢 Eugene 给予充分理解的回复,其他验证呢..?
    • 我希望我可以为您详细解答,但是我已经很久没有使用 Spring 验证了。 :( 由于 JSR 303 成为规范,而 Hibernate Validator 成为参考实现,我真的认为 Spring 会朝着同一个方向发展。
    猜你喜欢
    • 2018-06-20
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2012-05-24
    • 2014-10-05
    相关资源
    最近更新 更多