I am doing an user crud in spring-mvc.
My model has the following properties:
private Long id;
private String password;
private String username;
private Collection<Authority> myAuthorities;
private boolean isAccountNonExpired;
private boolean isAccountNonLocked;
private boolean isCredentialsNonExpired;
private boolean isEnabled;
I solved how to show the Authority
class in this question.
Now I am willing my form to be able to have a second password field to confirm that the user typed the password correctly.
I don't want to add a confirmPassword
property to the model, so my question is how to fix this the best way possible.
Edit:
Everything is working with axtavt's answer but I am missing a way to validate.
I have the following method in my controller, but even though I place a @Validate
ApplicationUserFormValidator
isn't called.
@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(Model model,
@Valid @ModelAttribute ApplicationUserForm applicationUserFrom,
BindingResult result) {
ModelAndView modelAndView = new ModelAndView();
if (result.hasErrors()) {
modelAndView.setViewName(USER_CREATE_FORM);
} else {
modelAndView.setViewName(REDIRECT_TO_USER_LIST);
modelAndView.addObject(USER_FORM_MESSAGE, USER_FORM_ADD_SUCCESSFUL);
applicationUserService.save(applicationUserFrom.getUser);
}
return modelAndView;
}
You may create an enclosing object to keep a confirmation:
public class ApplicationUserForm {
private ApplicationUser user;
private String confirmPassword;
...
}
-
Password: <form:password path = "user.password" />
Confirm password: <form:password path = "confirmPassword" />
Validator also works fine:
public class ApplicationUserFormValidator implements Validator {
public void validate(Object target, Errors errors) {
ApplicationUserForm f = (ApplicationUserForm) target;
if (!f.getConfirmPassword().equals(f.getUser().getPassword())) ...
errors.pushNestedPath("user");
new ApplicationUserValidator().validate(f.getUser(), errors);
errors.popNestedPath();
}
...
}
EDIT: If you use @Valid
annotation, you need to register a validator using @InitBinder
or in the config as described in the docs. You may also use a fully declarative JSR-303-style validation, but i'm not sure how will it play with business constraints such as user.password == confirmPassword
.
@InitBinder
public void initBinder(WebDataBinder b) {
b.setValidator(new ApplicationUserFormValidator());
}
add confirmPassword in your applicationUserFrom class
and add check function in setter
it's my best way
private String password;
@NotNull(message="not match")
private String confirmPassword;
public void setPassword(String password) {
this.password = password;
checkPassword();//check
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
checkPassword();//check
}
private void checkPassword() {
if(this.password == null || this.confirmPassword == null){
return;
}else if(!this.password.equals(confirmPassword)){
this.confirmPassword = null;
}
}
The way that I dealt with this was to put password confirmation and "are you sure you want to do this?" confirmation into the the access policy object that implemented fine-grained access control rules in the controller.
Rather than implementing user management all from scratch, you could use an off-the-shelf solution; e.g. Emmet. (Disclaimer - I'm the author.)