views:

20

answers:

2

I have a form to create a user and a corresponding command object. It looks like so:

public class CreateUserForm {
    private String name;
    private String email;
    private String password1;
    private String password2;
    private Boolean enabled = true;

    ... getters and setters ...
}

I have a user entity object that is to be created and stored based on the form input. The entity has annotated validation rules and looks like so:

@Entity
public class SiteUser {
    @Id
    private String id;

    @NotEmpty
    private String name;

    @NotEmpty
    @Email
    private String email;

    @NotEmpty
    @Pattern(regexp="^[a-zA-Z0-9_]{6,20}$")
    private String password;

    @NotEmpty
    private Boolean enabled;

    ... getters and setters ...
}

The form input should essentially have the same validation rules apart from the fact that the form input needs to check if the password1 and password2 fields are identical.

My first thought is to add the same validation annotations to the form object and create a custom validator that checks to see if the password1 and password2 fields are the same. However, I feel like I'm not doing something right by putting the same validation rules across two objects that are so similar.

So I'm looking for any advice on how to consolidate the process of validating and storing my entity based on the form input.

A: 

Why don't you use the domain object (i.e. SiteUser) in your UI? So, you won't have to duplicate the logic.

Eugene Kuleshov
Ahh...that makes sense. So I guess I would add password2 to the domain object and just annotate it so it won't be stored in the DB.
Matt W
A: 

You can do something like this:

public class CreateUserForm { 
    @Valid
    private SiteUser user;
    private String confirmPassword;
    ...
}

and check that confirmPassword.equals(user.getPassword()) manually.

Update:

Manual validation looks like this:

@RequestMapping(...)
public String createUser(@Valid CreateUserForm form, BindingResult result) {
    if (!form.getConfirmPassword().equals(form.getUser().getPassword())) {
        result.rejectValue("confirmPassword", ...);
    }
    ...
}

You can also implement a custom JSR-303 constraint to validate password confirmation along with other fields, but I think it's overkill in this case.

axtavt
Where would I perform the validation of the two passwords so that the error is registered in the binding result?
Matt W
@Matt: Updated.
axtavt
Tried this, but the annotated constraints in the SiteUser object aren't being recognized
Matt W
@Matt: It should work, note the `@Valid` at `user` field.
axtavt
Not sure what I did wrong the first time, but I got it working now. I like this approach. Thanks for the tip.
Matt W