Home > FAQs > How do we repopulate controls when validation fails |

Apache Struts 2 Documentation
How do we repopulate controls when validation fails
Edit Page Browse Space Add Page Add News

When validation fails, we typically forward back to the same server page, so that the errors can be presented, and so that the client can fix the problem and resubmit the form. Of course, aside from the errors, we may also need to present rich controls, like drop down lists.

If we try to populate rich controls in an `Action` method, like `input` or `execute`, and validation fails, the method will not be invoked, and the controls are not populated. Two alternative ways to populate controls are the `Preparable` interface and the `action` tag.

### Preparable interface

Instead of populating controls in an `Action` method, implement the `Preparable` interface, and use a `prepare` method instead. The `prepare` method is called before validation, so it validation fails, we still have a chance to populate controls (or whatever).

Input.jsp
Input.java (prepare)

If a custom stack is being used, be sure to put the Prepare Interceptor before the Validation Interceptor.

### action tag

Another solution is to use the action tag to execute an Action in place.

One way to use this tag is to put a control on a "snippet" JSP that is rendered as a result of an Action that does nothing but create the object that populates the control. The action tag sets "executeresult=true", then control markup will be "included" into the page (like a tile), after the action executes.

In effect, `exectuteResult` actions can be used like a tag that can run its own action before emitting the markup.

Input.jsp
Languages.jsp
Languages.java
struts.xml (Input, Languages)

The advantage being that the "Languages" action could be dropped in wherever the "Languages" control is needed, and that the Action for the form doesn't need to know how to populate the Languages control.

Now, the Action is going to be hit every time the page is rendered, but so long as you are using a caching data access layer, like IBATIS or Hibernate, it will end up being a memory-to-memory transfer, rather than a database access.