Apache Struts 2 Documentation > Home > Guides > Migration Guide > Struts 1 Solutions

This page is meant to be a list of issues and solutions that users ave encountered while migrating existing Struts 1 application to Struts 2, or developing new Webwork-based applications. If you have a solution to the issue that will of course be most helpful, but even if you don't it is worth noting what you encountered none the less in the hopes that someone else can come along and answer it for you, and the rest of us.

  • How do we change the location of the struts.xml file?
  • How do we set checkboxes to false (on uncheck)?
  • How can we set the focus on a form field?
  • What is the analogy to ForwardAction?
  • How do we extend an action mapping in struts.xml?
  • Can we use DynaBeans?
  • How do we set a token to track duplicate submits?

How do we change the location of the struts.xml file?

Struts 2 uses a different approach to loading the configuration. The initial struts.xml is loaded from the root of the classpath. The easiest way to set that up is to put the struts.xml under the classes folder.

If maintaining the struts.xml under classes doesn't work for you, then use the "bootstrap" struts.xml to include whatever other struts.xml's you'd like.

<struts>
   <include file="..\struts.xml"/>
</struts>

Or, chuck it all and use Zero Configuration

How do we set checkboxes false (on uncheck)?

In Struts 2, checkboxes are stateful, and we don't need to do that anymore.

Just treat the checkbox like any other tag. The framework will notice if a checkbox is "missing" from a request and inject a false value for that checkbox.

How can we set the focus on a form field?

Struts 1 generates a little JavaScript that helps set the focus, if you specify the field in the JSP.

Another solution is to use a generic Javascript that automatically seeks the first enabled form field on page.

(Building this script into Struts 2 is being considered.)

What is the analogy to ForwardAction?

The default Action class (ActionSupport) returns SUCCESS by default, and SUCCESS is the default result. Using an action to forward directly to a page is easy:

<action name="Welcome" class="com.company.Foo">
<result>/pages/Welcome.jsp</result>
</action>

How do we emulate the default="true" attribute of a Struts 1.x Action mapping?

Rather than tag the action as being the default, the default action is set by name using default-action-ref element.

<default-action-ref name="defaultAction">

By using an element, rather than an attribute, packages can inherit the default action name.

How do we extend an action mapping in struts.xml?

Starting in Struts 1.3, we can use the "extends" attribute in our Struts configuration Action mapping to have it inherit properties from a base mapping. In Struts 2, that technique is no longer necessary because we have packages. We can create a package, then set for that package the default Result type, Interceptor chain, and global results. This leaves very little information to actually be included in an action element.

Here is an example of declaring a custom package:

<package name="chat" extends="struts-default" namespace="/chat">
  <global-results>
    <result name="login" type="freemarker">/chat/chatLogin.ftl</result>
  </global-results>
  <default-interceptor-ref name="basicStack"/>
  ...
</package>

In fact, packages themselves can extend other packages, as the "chat" package extends "struts-default" in the above example.

Can we use DynaBeans?

Sure, but first, ask "Do we want to use DynaBeans at all?"

Typically, DynaBeans are used to emulate a plain old JavaBean that is utilized by the business logic. If that is the case, then we can just use the plain old JavaBean directly. Struts 2 will happily cope with rich properties, like date fields. We don't have to reduce everything to a String anymore.

Otherwise, DynaBeans can be treated as a regular Java object, if the particular implementation contains a getMap() method. This method lets OGNL, the Struts 2 expression language, know how to access and set data. DynaBean variants like the LazyDynaBean can create themselves on-the-fly, where other more static types might need to be created in your Action's constructor before being used.

How do we set a token to track duplicate submits?

In Struts 2, there shouldn't be any token code in an Action class at all. The Interceptors are designed to do all the work. There are three flavors, the Token Interceptor, the Token Session Interceptor, and the Execute and Wait Interceptor.

Token Interceptor

The Token Interceptor is most like the Struts 1 approach, except that we don't have to change the Action class to add a lot of busy code. The trade off is that we do have to include the token tag in the form, to bootstrap the process. In Struts 1, we set the token in the Action, and the form tag detected it. In Struts 2, we set the token in the page, and the Interceptor detects it.

If the Interceptor does detect a duplicate submit, then it automatically returns an "invalid.token" result code, which can be handled via the action mapping.

Token Session

The Token Session Interceptor tries to be even more automatic by attempting to display the same response that the original, valid action invocation would have displayed if no multiple requests were submitted in the first place.

Execute and Wait

The Execute and Wait Interceptor embraces long-running taks by presenting a progress meter as the Action runs in the background.

Next: What is the ActionContext?


This material originally adopted from: http://wiki.apache.org/struts/IssuesAndSolutions.