Spring 3 基于注解的验证:密码和确认密码

Posted

技术标签:

【中文标题】Spring 3 基于注解的验证:密码和确认密码【英文标题】:Spring 3 annotation-based validation: password and confirm password 【发布时间】:2011-11-06 13:58:03 【问题描述】:

在我的 Spring 3 MVC 应用程序中,用户需要保存密码,如果他们还能够在保存时确认密码,这将是一个不错的功能。

在 bean 中,我使用基于注释的验证。是否有可用于执行此检查的注释验证器?

经过一番谷歌搜索后,我找到了这个博客:http://gochev.blogspot.com/2010/06/spring-mvc-spring-bean-validation.html。但我想我在这里缺少一个 jar-lib,因为 Eclipse 无法找到/建议任何 jar。有人知道我需要什么罐子才能工作吗?

提前谢谢:)

【问题讨论】:

【参考方案1】:

Cyril Deba 提供的公认解决方案也对我有用。但是后来我不得不为 ResetPassword 和 ChangePassword Page 做另一个注释,因为它们有不同的 DTO。为了克服这个问题,我将 isValid 更改为以下代码。虽然也可以通过实现接口来实现,但我认为这个更现实。希望它会有所帮助。

@Override
public boolean isValid(Object candidate, ConstraintValidatorContext context) 

    try 
        Method methodGetPassword = candidate.getClass().getMethod("getPassword");
        Method methodGetConfirmpassword = candidate.getClass().getMethod("getConfirmpassword");

        if(methodGetPassword.invoke(candidate) == null && methodGetConfirmpassword.invoke(candidate)==null) 
            return true;
        else if(methodGetPassword.invoke(candidate) == null )
            return false;
        return methodGetPassword.invoke(candidate).equals(methodGetConfirmpassword.invoke(candidate));

     catch (NoSuchMethodException ex) 
        ex.printStackTrace();
        return false;
     catch (Exception ex) 
        ex.printStackTrace();
        return false;
    

【讨论】:

【参考方案2】:

我写了以下代码来验证密码:

约束实现:

 package com.test.web.validation.user;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target( ElementType.TYPE )
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = PasswordsEqualConstraintValidator.class)
public @interface PasswordsEqualConstraint 
String message();

Class<?>[] groups() default ;

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


package com.test.web.validation.user;

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

import com.test.logic.dto.UserDto;

public class PasswordsEqualConstraintValidator implements
    ConstraintValidator<PasswordsEqualConstraint, Object> 

@Override
public void initialize(PasswordsEqualConstraint arg0) 


@Override
public boolean isValid(Object candidate, ConstraintValidatorContext arg1) 
    UserDto user = (UserDto) candidate;
    return user.getPassword().equals(user.getPasswordRepeat());


我的 DTO 对象:

package com.test.logic.dto;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import com.esldic.web.validation.user.EmailExistsConstraint;
import com.esldic.web.validation.user.PasswordsEqualConstraint;

@PasswordsEqualConstraint(message = "passwords are not equal")
public final class UserDto extends AbstractDto implements Serializable 

private static final long serialVersionUID = 1L;

private Long id;

@NotNull
@Size(min = 3, max = 30)
@EmailExistsConstraint(message = "email is not available")
private String email;

private String username;

@NotNull
@Size(min = 2, max = 30)
private String password;

@NotNull
@Size(min = 2, max = 30)
private String passwordRepeat;
...

最后,我的控制器

package com.test.web.controllers;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.test.logic.dto.UserDto;

@Controller
public final class SignupController 

@Autowired
private Validator validator;

@RequestMapping(value = "/signup.html", method = RequestMethod.POST)
public @ResponseBody
ModelAndView handleSignupForm(@ModelAttribute UserDto candidate,
        HttpServletResponse response) throws ServiceException 
    Set<ConstraintViolation<UserDto>> failures = validator
            .validate(candidate);

    if (!failures.isEmpty()) 
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        return ValidationHelper.validationMessages(failures);

     else 
        return userService.create(candidate);
    

另外,在 google 中你会发现很多带有 JSR-303 bean 验证的示例。

【讨论】:

【参考方案3】:

您需要 Hibernate Validation 和 JSR 303 Api jar。

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.1.0.Final</version>                        
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.0.0.GA</version>
    </dependency>
http://mvnrepository.com/artifact/org.hibernate/hibernate-validator http://mvnrepository.com/artifact/javax.validation/validation-api/1.0.0.GA

看到这个问题:Cross field validation with Hibernate Validator (JSR 303)

有几种方法可以解决这个问题。

【讨论】:

以上是关于Spring 3 基于注解的验证:密码和确认密码的主要内容,如果未能解决你的问题,请参考以下文章

Angular使用总结 ---以密码确认为例实现模版驱动表单的自定义校验

django 基于 form 验证 确认密码的注册

验证密码和确认密码

hapi route joi 验证密码确认

带密码确认的引导 4 验证并禁用提交,直到表单验证(注册表单)

在PHP中验证密码和确认密码