Blah, multipage forms suck. 😉 Alright, I’m not making it a lot easier for myself by insisting on using DispatchActions, but hell, it should support it.
Problem 1 – One action mapping can only have one input. This doesn’t matter when everything looks fine, but suddenly you get a validation error, and Struts tries to redirect to the first inputpage, even though the validation error occurred on page 2. With two action mappings this would of course be solved.
Problem 2 – Whenever validation fails it will redirect back to the input page. This is without touching the Action. This means that any setup you do, and things you put in the request before the page is displayed is gone. Big problem with dropdown select boxes. After failed vaildation the collection used to populate it in the request is gone and the tags fail with an Exception screaming about not finding it.
Solution – Turn off validation in the mapping and call form.validate() explicitly at the beginning of your next action step. If the validation returns errors, setup the necessary content in the request, and then forward to the page again. Not too nice. I’d rather have the Action implement a setupForm method or something.
// Validate input from previous form
ActionMessages ae = form.validate(mapping, req);
if (!ae.isEmpty()) {
this.saveErrors(req, ae);
setupStep1(req);
return mapping.getInputForward();
}
Maybe there’s some features I’m overlooking, but I’ve tried to find any info. There are lots of old posts on the mailinglists about especially problem 2, but the solution I found was to turn off validation. This seems to be an old problem, and one I have encountered several times, so I’m a bit surprised it hasn’t been incorporated into Struts yet. Or maybe it is?
Drop me a line if you have got some more info.
Update: Seems Rick Reumann has encountered the same problem here. He reaches pretty much the same conclusion as me. I’m not sure I like the solution yet, but one thing it lead me to was to structure my code better by separating out the setup code for the form in each action method.
3 replies on “Struts and multipage form validation”
I agree, the solution is not great. Why can Struts not duplicate the request attributes if the validate fails into the new request. Surely semantically by “going back to the original page” on validation failure ALSO means replicating the state of the original page too, i.e the request. Having to go with extending DynaActionForm and overriding validate for now.
The problem is that it has no way to know the parameters. And it can’t simply run the action again, cause that could mean storing information in duplicat. That’s why you need some kind of setup method that does just what is needed for the form.
The setup/explicit validation method is working good for me. Maybe they will do a setup/automatic validate feature later on but it’s no biggie. I just wish I had the time to contribute it, cause it shouldn’t be a very big deal.
Another option is to implement validate in your form to set a boolean flag ‘validationRequired’. If your action is reached and the boolean flag is set, you call the form explicitly. In this way, you can use the validate flag in struts, but call the validate in your own abstract action.