SPECIAL NOTE ON UPGRADING - README FIRST! - If you use the standard CANCEL BUTTON in your application and validate is set to true for that mapping, you MUST also specify "cancellable=true" in the mapping, otherwise, an InvalidCancelException will be thrown if the Cancel button is used. See the new Opt-In Cancel Handling feature for more.
<action path="/ActionThatCanBeCancelled" validate="true" cancellable="true" ... </action>
This section contains release notes for changes that have taken place to the seven new subprojects known as "Struts Classic" since Version 1.2.9 . To keep up-to-date on all changes to Struts, subscribe to the (commits at struts.apache.org) list. To preview our plans for upcoming changes, please visit the Roadmap page .
Notes on upgrading are maintained in the Wiki Upgrade pages . The wiki is a community maintained resource - please feel free to add your input so that everyone can benefit from the collective experience.
For the version requirements of each library, see the Installation chapter .
The purpose of this section is to highlight the new features since the Version 1.2.8 release. For more detail, see the Project Info reports for each subproject, which include a complete changelog and list of external dependencies.
You can also access to the Apache Struts source repository and change logs directly through both web browser and Subversion client interfaces.
On the volunteer front, eight new committers accepted invitations to join us. We welcome Wendy Smoak , Gary VanMatre , Sean Schofield , Greg Reddin , Laurie Harper , Richard Feit , Jason Carreira , and Patrick Lightbody .
We also welcome Wendy Smoak and Gary VanMatre to the Apache Struts PMC (Project Management Committee).
Since Struts 1.2.8, we have subdivided Struts into several subprojects, each with its own release cycle. The set of seven subprojects derived from Struts 1.2 is sometimes referred to as "Struts Classic". The Struts Classic subprojects are Action, Applications, EL, Extras, Site, Taglibs, and Tiles. These subprojects will all inherit version 1.3.0, but, thereafter, subproject revisions will increment independently of each other.
Since many teams will use Struts with one or more extensions, we are bundling the jars for extensions that utilize the framework into a single distribution called "Struts Library".
The Apache Struts subprojects, including the website, are being built with Maven. But, of course, you can continue to build your own projects any way you like!
The 1.3.x series of Struts now has a minumum requirement of the following specification versions:
A number of software dependency changes apply to this release:
The applications have been moved into their own subproject, the builds have been "Mavenized", but the set of example applications is essentially unchanged.
Major changes to the framework include
In prior versions, the request processing guantlet is represented as a series of methods. While it was easy to override the methods to provide different functionality, it was not easy to use multiple extension that each wanted to override the request processor in a different way.
public void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { processLocale(request, response); if (!processRoles(request, response, mapping)) { return; } /// ... ActionForward forward = processActionPerform(request, response, action, form, mapping); processForwardConfig(request, response, forward); }
For Action 1.3, we turned the request processor methods into Commands that are part of a flexible Chain of Commands. Rather than subclassing a monolithic object, we can now just replace Commands. Commands can also be inserted or removed, if needed, to extend or streamline the request processing gauntlet to meets the needs of different kinds of applications.
<chain name="process-action"> <command className= "...SelectLocale"/> <command className= "...AuthorizeAction"/> <!-- ... --> <command className= "...CreateAction"/> <command className= "...ExecuteAction"/> </chain>
We fully expect the Action 1.3 request processor to be backwardly compatible with earlier versions. But, to be prudent, we wanted to release 1.3 with the Composable Request Processor before making additional changes.
We've made a few other changes and improvements in Action 1.3.x, but the two big-ticket items are subprojects and the new request processor.
If needed, the monolithic RequestProcessor from Struts 1.2 is still available in the distribution and may be configured via the controller element.
<controller processorClass="org.apache.struts.action.RequestProcessor" />
However, we consider this RequestProcessor to be a legacy class. Once the new ComposableRequestProcessor is more-widely field tested, we expect that this class will be deprecated, moved to the Extras subproject, and ultimately removed. Accordingly, some new features, like Opt-In Cancel Handling, are only supported by the new Composable Request Processor.
Most every Struts configuration element now accepts a map of key/value pairs. Arbitrary configuration properties let us externalize more of our configurations, encouraging reuse.
<action path="/EditSubscription" extends="Editor"> <set-property key="foo" value="bar"/> </action> public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { string foo = getProperty("foo"); // ...
Arbitrary Configuration should make it easier for everyone to write reusable chunks of code, for ActionMappings, Exception Handlers, and other members.
SPECIAL NOTE ON UPGRADING - README FIRST! - If you use the standard CANCEL BUTTON in your application and validate is set to true for that mapping, you MUST also specify "cancellable=true" in the mapping, otherwise, an InvalidCancelException will be thrown if the Cancel button is used. Here's why:
In Struts 1.2.8 and prior, any time the magic token generated by the Cancel tag is found in the request, validation for the ActionForm is skipped. Accordingly, in Struts 1.2.8 and prior, any Action that relies on validation should always observe the isCancelled method.
In Struts 1.3, the Cancel token is only honored if the new property "cancellable" is set for the Action Mapping. If the Cancel token is present, but cancellable is not set, then an InvalidCancelException is thrown. The InvalidCancelExeption may be caught by a Declarative Exception Handler, like any other Exception.
<action path="/ActionThatCanBeCancelled" validate="true" cancellable="true" ... > <exception key="errors.invalidCancel" type="org.apache.struts.action.InvalidCancelException" path="/InvalidCancelException.jsp"/> </action>
The declarative exception handler is optional. The Exception will only be thrown when there is a programming error or when a rogue client is trying to bypass validation.
Note that the Opt-In Cancel Handler is available for the Composable Request Processor as well as the legacy Request Processor included in Struts 1.3.
We now support use of global exception handlers in cases when no ActionConfig has yet been identified, as in with "preprocessing" commands in a custom request processing chain. In the case when there is no ActionConfig, the AbstractExceptionHandler will now call a new method in ModuleConfig which provides similar logic for finding a globally mapped exception handler for the given exception class or any of its superclasses.
Available for both the Controller and any Action Mapping
catalog - The name of a commons-chain catalog in which to look up a command to be executed as part of servicing this request. Only meaningful if "command" is also specified.
command - The name of a commons-chain command which should be looked up and executed as part of servicing this request.
<controller inputForward="true" catalog="Foo" command="FooBar" />
In the Struts configuration file, we can now use the extends attribute to adopt default settings from another element, as we already can in the Tiles configuration files.
<struts-config> <form-beans> <form-bean name="registrationForm" type="org.apache.struts.action.DynaValidatorForm"> <form-property name="firstName" type="java.lang.String" /> <form-property name="lastName" type="java.lang.String" /> </form-bean> <form-bean name="managerRegistrationForm" type="org.apache.struts.action.DynaValidatorForm" extends="registrationForm"> <form-property name="department" type="java.lang.String" /> </form-bean> </form-beans> ... </struts-config>
Extends makes using XML elements much more like object-orientated programming. You can setup a base element, and then only specify the behavior that changes. Extends lets us set default values and then "program by difference". When elements are not relentlessly chanting the same things over and over, it's easier to see the forest for the trees.
When using Tiles, sometimes the response is already
committed when an exception occurs.
Now, the ExceptionHandler tests
response.isCommitted
,
and, if true, includes the configured view path, rather
than forwarding to it.
The updated ExceptionHandler accepts new configuration
attributes which let you
choose alternate behavior, or no behavior at all. See the
JavaDoc for details.
<exception key="GlobalExceptionHandler.default" type="java.lang.Exception" path="/ErrorPage.jsp"></exception> <exception key="GlobalExceptionHandler.default" type="java.lang.Exception" path="/ErrorPage.jsp"> <set-property key="SILENT_IF_COMMITTED" value="true" /> </exception>
The action attribute of the Form taglib is now optional. If omitted, the original URI of the original request is used.
<html:form onsubmit="return validateLogonForm(this);">
Wildcards can now be used in the properties of an ActionConfig. This makes it easier to pass multiple request-time values to the Action without complicating the "parameter" attibute.
<action path="/Save*" name="Save{1}" extends="BaseSave"> <set-properties key="Save" value="{1}"/> </action>
Aside from addressing deprecations, there were a few minor changes to Struts EL.
This subproject was extracted from the Actions and Plugins packages of Struts 1.2. The code itself is unchanged except for one minor issue.
The new Site subproject hosts the top-layer of the Struts website, and serves as a portal to the other subprojects.
We're changed the way we generate our reference documentation for the taglibs, but we think you will find the new reference just as useful as the old. Otherwise, we made only minor fixes to the trusty Struts Taglibs.
false
in the JavascriptTag.
Tiles is being refactored into a standalone package that can be used with or without Struts. For more on how this affects Tiles users, see the Tiles subproject site.
Next: Installation