Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating wizard pages with Spring 3

I started researching how to create a controller for a wizard-like form in Spring and came across the AbstractWizardFormController, which I quickly noticed was deprecated.

I then dug a bit further and found how to accomplish something similar with Spring 3. This example does not do any sort of validation though (e.g. via @Valid), so I'm wondering how does one validate each step of a wizard?

Would it be possible for each step have its own backing Form object and then use @SessionAttributes to store their values for when a final submit is called (presumably on the last page of the form)?

Thanks for any help.

(P.S.: Solutions that don't require WebFlow would be ideal.)

like image 971
Ryan Avatar asked Jan 19 '23 04:01

Ryan


2 Answers

I don't know of a way to pull this off with the @Valid annotation, but you should be able to take advantage of the JSR-303 validation to accomplish this. As a somewhat contrived example:

public class User {
    @NotNull(message = "First name can't be blank", groups = {Step1.class, FinalStep.class})
    private String firstName;

    @NotNull(message = "Last name can't be blank", groups = {Step1.class, FinalStep.class})
    private String lastName;

    @NotNull(message = "Email can't be blank", groups = {Step1.class, FinalStep.class})
    private String emailAddress;

    @NotNull(message = "Please provide a valid address", groups = {Step2.class, FinalStep.class})
    private Address address;

    // getters/setters...

    public interface Step1 {}
    public interface Step2 {}
    public interface FinalStep {}
}

You can take advantage of the fact that JSR-303 supports validation groups by providing marker interfaces to represent your wizard steps.

Then, instead of relying on the @Valid annotation, inject a Validator instance into your controller and call:

validator.validate(user, /*<step interface>.class*/);

in your processPage method (referencing Controller in your linked question), and then

validator.validate(user, FinalStep.class);

in your processFinish call.

like image 108
Jeff Avatar answered Jan 30 '23 20:01

Jeff


Use @Validated.

From Spring's documentation:

Variant of JSR-303's Valid, supporting the specification of validation groups. Designed for convenient use with Spring's JSR-303 support but not JSR-303 specific. Can be used e.g. with Spring MVC handler methods arguments. Supported through SmartValidator's validation hint concept, with validation group classes acting as hint objects. Can also be used with method level validation, indicating that a specific class is supposed to be validated at the method level (acting as a pointcut for the corresponding validation interceptor), but also optionally specifying the validation groups for method-level validation in the annotated class. Applying this annotation at the method level allows for overriding the validation groups for a specific method but does not serve as a pointcut; a class-level annotation is nevertheless necessary to trigger method validation for a specific bean to begin with. Can also be used as a meta-annotation on a custom stereotype annotation or a custom group-specific validated annotation.

like image 40
Shahed Avatar answered Jan 30 '23 20:01

Shahed