Learning the New Jakarta Struts 1.1, Part 2
Pages: 1, 2
path attribute is the application-relative path of the resource to forward to if this exception occurs. The
scope attribute can be set to either
session, and indicates where the
ActionError will be made available. Last but not least is the
type attribute. This is the fully-qualified Java class name of the exception to be handled. (What a mouthful.) Here's a sample:
In struts-config.xml, we first declare our
<global-exceptions> in the following format:
<global-exceptions> <exception key="error.required" type="org.apache.struts.util.AppException" path="/appError.jsp"/> </global-exceptions>
Here we are declaring that any Action (or business logic) that throws the
AppException will be sent to appError.jsp. We are associating the
error.required message string from our
ApplicationResource file with this exception. The
ApplicationResource file is discussed in detail in Chapter Nine of my book, The Struts Framework: Practical Guide for Java Programmers (2002, Morgan-Kaufman), when we talk about internationalization. If you view the mainMenu.jsp file in our sample application, there is a link to force an application exception. This makes it easier for you to quickly force an error exception and to follow the flow in the ForceErrorAction.java file. You can add as many
<exception> elements to the
<global-exceptions> as you like.
Next we'll look at a specific Action exception declaration.
<action path="/insert" ... <exception key="error.required" type="cdmanager.exceptions.MissingValueException" path="/insertError.jsp"/> </action>
In this case, we are declaring that if the
InsertAction (or business logic used by the
InsertAction) throws the application-specific exception
MissingValueException, then send the exception to insertError.jsp. Note that in this example, we have defined a specific application exception. This is helpful if you want to wrap other, less helpful exceptions. For example, you might want to catch
SQLExceptions and re-throw them as application-specific exceptions with a more meaningful message to the user.
It is also worth pointing out that matching exceptions to exception handlers takes inheritance into account (i.e., you can declare a handler for a superclass and handle all of the exceptions for subclasses of that exception class as well.) The matching algorithm works identically to the one used by the servlet container to select
<error-page> matches for exceptions.
Upgrading From Struts 1.0.2
If you are upgrading an existing Struts application to v1.1, you should not have that many worries. The development team did a very good job of keeping Struts backwards-compatible. For all intents and purposes, you should have little trouble upgrading to v1.1. While each application is different, here are some general rules of thumb to use when evaluating your application.
Many of the Struts
util packages have been moved to Jakarta Commons, so you may need to adjust some package names in your code. This should be as simple as a global find and replace.
In order for this sub-app feature to work, any request for a presentation page that uses elements from the configuration file, including
Action Mappings, must be routed through the controller. This allows the controller to make the appropriate configuration available for a given page. Having requests pass through the controller is not new to Struts 1.1. While it might have been possible to bypass this by having direct linking to pages, it is good design practice to make sure everything flows through the controller. When using the MVC model, this is the way it should be, anyway. Many other features in advanced applications, including security and logging, are easier to implement when everything passes through the controller.
Perform Vs. Execute Methods
In Struts 1.x,
Action.perform() is the method called by the
ActionServlet. This is typically where your business logic resides, or at least the flow control to your JavaBeans and EJBs that handle your business logic. As we already mentioned, to support declarative exception handling, the method signature changed in
execute just throws
Action.perform() is now deprecated; however, the Struts v1.1
ActionServlet is smart enough to know whether or not it should call
execute in the Action, depending on which one is available.
Changes to Build Files
If you are building with ANT, you might need to adjust your build.xml to include the Jakarta Commons library files. To make sure you don't run into classloader issues, check the
struts-user mailing list if your container is having problems.
Other Things to Watch For
I've taken Struts v1.x applications and run them within minutes on Struts v1.1. However, there are a couple of things that you should be aware of if you've taken advantange of some of the more advanced features. For example, the
ApplicationConfig object is used now to handle Servlet context attributes per sub-application. This means that if you are using information from any of the various objects in Struts that handle your application collections, like
ActionMappings, you'll need to reference them through
ApplicationConfig. Also, if you have done any
ActionServlet-specific work for your
ActionServlet, you might want to take a look at the changes that have taken place regarding the
Struts v1.1 offers us some new and exciting features for Web application development. You should be able to start taking advantage of them as soon as you're done with this article.
Read more JSP and Servlets columns.
Return to ONJava.com.