I have implemented form validations (using validation.xml), and am wanting to know if theres a 'best practice' for doing this, as I believe the way I have implemented this would not be considered 'best practice'. I'm using Struts 1.2.4.
For a simple form that displays and allows the changing of a record in the db, I have found that I need to: 1) Put the java bean that populates the form fields as an attribute on the session. If I put it as an attribute on the request and the validation fails, then I get an exception when the page is redisplayed saying that my Bean cannot be found. 2) Given that the bean is on the session, when the JSP redisplays due to a validation error then the form is displayed with the orginal values from the javabean - hence, all previous changes the user made are lost. For instance if I clear a field that has a validation of 'required' then when the form is displayed due to the validation error, this field will be redisplayed with it original contents from the javabean. 3) Given that the bean is on the session, it presents a potential memory leak if I dont remember to remove it.
something is not quite right... you are NOT required to have the bean placed in session for declarative validations unless you are using indexed properties in your form.
you are using a java bean to populate your form? not form-bean configurations and struts-html tag-lib to build your form?
i apologize if some of these steps are elementary, but here's how i normally set up my validation (through many trials and errors). imagine you have a login form where the username is presented based on a userid stored in a cookie from the last access (an unlikely scenario, but it covers db retrievals).
1. set up 1 form-bean <form-bean name="LoginForm" type=".....DynaValidatorForm"> <form-property name="username" .../> <form-property name="password" .../> </form-bean>
2. set up 2 action mappings that are mapped to the same form-bean a. <action path="login/entry" name="LoginForm" type="com.my.actions.LoginEntryAction" ...> b. <action path="login/submit" name="LoginForm" type="com.my.actions.LoginSubmitAction"...validate="true" input="/login/entry.do">
3. in your LoginEntryAction.execute() a. retrieve the username from the DB b. do form.set("username", dbVO.getUserName()); c. forward...
4. your tiles/jsp should contain... a. <html:form action="login/submit"...> b. <html:input property="username"/> and <html:input property="password"/>
5. configure your validation.xml (i assume you know how)
when the user access login/entry.do, the form will be presented with the username pre-populated. assuming you have "password" defined as 'required', struts will automatically re-populate the form with the username upon failed validation (password field left blank).
of course you can also use DispatchAction and validwhen to do your validation depending on the dispatch method called.
the key to this whole thing is the usage of 2 action mappings and the use of the struts-html tag library. if you have 1 action mapping, validation will be called at all time (the user will always get the error message - password is required). if you are using plain old HTML and view beans to manually populate your forms, you're in for many nightmares to come, especially comes the time of indexed properties.
-/a<br />certified slacker...yes, my last name is 'do' - <a href="http://www.luckycouple.com" target="_blank" rel="nofollow">luckycouple.com</a>
Joined: Apr 26, 2005
Thanks for that Alan, as I didnt know you could set the html fields via setting the properties of the form - rather than using a Javabean as I was.
With html drop downs, given that these can accept a collection I'm assuming that the collection has to be placed on the session? I assume an indexed property as you spoke about is the same an an array of collection, etc?
Joined: Apr 14, 2005
when i started out with struts, i wish someone told me A LOT of things
collections for dropdowns can be placed in the request if you want. you'll have to manage that at each action. in other words, if they are not too huge, you can set them in the session and forget them. to pre-select the dropdown value, you'd do the same as you would with any other form elements.
you are correct regarding indexed properties having to deal with arrays. the best example i can give you is a shopping cart which contains an unknown number of line items. if you have a shopping cart form-bean, using indexed properties would mean the form-bean definition will contain <form-property name="lineItems" type="my.objects.LineItem"/>. struts handle this using the indexed="true" attribute in the struts-html tags (along with some other steps you need to follow). neat stuff, but it has its limits.