Although the web.xml file is used for configuring any generic web application, there are a few Struts-specific configuration options that you must configure within this file when using the Struts framework. The next section describes the necessary steps that you’ll need to perform to ensure that your Struts application is properly configured.
The first and perhaps most important step that you need to perform is
to
configure
the ActionServlet
that will receive all incoming
requests for the application.
Tip
You need to configure only a single ActionServlet
,
regardless of the number of subapplications that are being used. Some
developers choose to set up multiple controller servlets to handle
different functional areas of the application. Because servlets are
multithreaded, you don’t gain any real performance
or scalability value by using multiple
ActionServlet
mappings.
Currently, the Struts framework allows only a single controller
servlet to work. This problem surely will be fixed in a future
release and might even be resolved before 1.1 goes final. However,
you should verify that the problem has been fixed before attempting
to use multiple controllers in your application.
There are two steps in configuring the
Struts controller servlet in the web.xml file. The first step is to use the
servlet
element to configure the servlet
instance that can later be mapped in the
servlet-mapping
element. The child elements that can be
used in the servlet
element are shown here:
<!ELEMENT servlet (icon?, servlet-name, display-name?, description?, (servlet-class|jsp-file), init-param*, load-on-startup?, run- as?, security-role-ref*) >
The child elements that we are most interested in are
servlet-name
,
servlet-class
, and
init-param
. The servlet-name
elementspecifies the name used by the
deployment descriptor to reference the servlet throughout the
remainder of the file. When you’re configuring the
servlet-class
element for a Struts application,
this element must specify a fully qualified class that extends the
org.apache.struts.action.ActionServlet
class.
Tip
Because the Struts ActionServlet
class is not
abstract, you are free to use that class and avoid having to create a
subclass of the ActionServlet
for your
application. With earlier versions of the Struts framework, it was
more important to extend the ActionServlet
class
with one of your own because most of the processing occurred there,
and subclassing allowed you to override that functionality with your
own. With Version 1.1, however, most of the processing functionality
has been moved to another class, which you can configure
declaratively (as you’ll see later in this chapter).
There is little reason to create your own
ActionServlet
class, although you are still free
to do so.
The following web.xml
fragment illustrates
how to use the servlet
element to configure the servlet
class:
<web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> </servlet> </web-app>
The next step that needs to be performed to configure the Struts
controller servlet in the deployment descriptor is to configure the
servlet
mapping. This is done using the servlet-mapping
element. The following partial deployment descriptor illustrates how
to combine the
servlet-mapping
element with the servlet
element shown previously:
<web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>storefront</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
Notice that the value in the
servlet-name
element within
the servlet
element must match the value in the
servlet-name
element within the
servlet-mapping
element. This tells the web
container that the ActionServlet
should service
all requests having an extension of .do.
This is a good time to digress for a moment
and discuss how the URLs that a user types into a browser are mapped
to the correct web application and servlet. When a web application is
installed in a container, the container is responsible for assigning
a ServletContext
to it. There is a single instance
of a
ServletContext
object for each
web application deployed in a
container.
Tip
If the container is distributable and uses more than one JVM, the web
application may have a separate ServletContext
instance for each JVM.
The ServletContext
provides an external view of
the web container environment for a servlet. A servlet can use the
ServletContext
object to gain access to
external
resources, log events, and store attributes and objects that other
servlet instances in the same context can access.
It’s essentially an
application-scope shared resource.
Because a servlet is associated with a specific web application, all requests that begin with a specific request path (known as the context path ) are routed to the web application associated with that servlet. Servlets associated with the default application have an empty string (“”) as the context path.
When a web container receives a client request, it must determine the correct web application to forward it to. The web container determines this by matching the URL with the longest context path that matches an installed web application.
For example, suppose that there are two web applications installed in a container. One web application is given the name Storefront and is located off the root directory of the container at /storefront. The second web application is called Storefront_demo and is located off the root directory at /storefront_demo.
If a client request arrives at the server with a URL of http://www.somehost.com/storefront_demo/login.do, the server will match it to the web application that has the closest match, which in this case would be the Storefront_demo application. Once the container determines the correct context or web application, it must determine which servlet in the web application should process the request. The web container uses the request URL, minus the context path, to determine the path that will be used to map the request to the correct servlet.
The web container uses the following guidelines to find the first successful match:
The container attempts to locate an exact match of the request path to the path of a servlet.
The container recursively tries to match the longest path prefix. The servlet that contains the longest match, if any, is selected.
If the URL path contains an extension—for example, .do—the servlet container tries to match a servlet that handles requests for that extension. The extension is defined as the part of the segment after the last dot (.).
If none of the previous rules produces a match, the container attempts to use a default servlet, if one is configured. Otherwise, the request returns an error response.
The concept of extension mappings was mentioned in Step 3 of the
matching guidelines. There is another type of mapping that can be
used, known as path
mapping
.
A servlet-mapping
that uses path mapping allows a
URL that doesn’t contain an extension to match to
the servlet. Using the earlier Storefront
servlet mapping, the following partial
web.xml
file illustrates how
path mapping is configured:
<web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>storefront</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> </web-app>
Using path mapping, all requests mapped to this web application that contain the string “/action” in the request URL will be serviced by the Storefront servlet, regardless of what is in place of the * character.
As was briefly discussed in Chapter 3, the Struts
1.1 release added the ability to define multiple Struts configuration
files, one for each supported application module. In previous
versions of the framework, you specified a relative path to the
single Struts configuration file using the config
initialization parameter. With Version 1.1 and introduction of the
concept of application modules, you can now create multiple Struts
configuration files and specify them in the web.xml file using
multiple
config
initialization parameters and the
application module prefix. The next section discusses the
initialization parameters that can be configured for a servlet.
Initialization parameters are used to make configuration options
available to a servlet. This allows the developer to declaratively
affect the runtime environment of the servlet. Initialization
parameters are configured within the
servlet
element using
init-param
elements, as shown in the following
web.xml
fragment:
<web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>host</param-name> <param-value>localhost</param-value> </init-param> <init-param> <param-name>port</param-name> <param-value>7001</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>storefront</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
You can specify any parameter you need within the
init-param
element, as long as
it’s a name/value pair. For example, the previous
web deployment descriptor included initialization parameters for a
host
and port
. If you were
using EJB, this might be a way to include the server connection
information. Zero or more init-param
elements are
allowed.
There are specific initialization parameters that can be specified
for the Struts servlet. In earlier versions of Struts, many of the
configuration options that are now in the Struts configuration file
were configured by adding init-param
elements.
Although applications that were built and tested with Version 1.0
will continue to work using Version 1.1, you may want to move some of
the initialization parameters that currently are specified in the web
deployment descriptor to the proper location in the Struts
configuration file. Although the framework includes functionality
that allows the previous initialization parameters to work in the
web.xml file, we will cover the
1.1 parameters here. Table 4-2 identifies the
initialization parameters that can be specified for Struts 1.1.
Table 4-2. Initialization parameters for web.xml using Struts 1.1
Name |
Purpose/default value |
---|---|
A context-relative path to the default Struts configuration file. The
default value is | |
You can specify additional subapplications by using the value
| |
The debugging detail level for this servlet, which controls how much
information is logged. This parameter is optional and defaults to
| |
The debugging detail level for the Digester, which logs information
as it parses the configuration files. This parameter is optional and
defaults to | |
If this Boolean value is set to |
Tip
If you are supporting a Struts 1.0 application using the 1.1 release, the web.xml file may contain many of the configuration parameters that are now defined in the Struts configuration file. The parameters apply only to the default application and will eventually be removed in future releases. It’s better to get used to setting them in the Struts configuration file.
The Struts framework provides several JSP tag
libraries that you must configure in the web application deployment
descriptor if you choose to use them. You inform the container of
these tag libraries by declaring one or more
taglib
elements within the web deployment
descriptor. The following partial web.xml
file illustrates how
the tag libraries are configured within the
web-app
element:
<web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>host</param-name> <param-value>localhost</param-value> </init-param> <init-param> <param-name>port</param-name> <param-value>7001</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>storefront</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> </web-app>
The taglib
element has two subelements:
taglib-uri
and
taglib-location
. The taglib-uri
element specifies a URI identifying a tag library that is used by the
web application. The value may be either a relative or an absolute
URI. It must be a valid URI, but here it’s used as a
unique identifier for the tag library. The
taglib-location
element specifies the location (as
a resource) of the tag library descriptor file.
The Struts tag libraries are not the only ones that can be declared
in the web application deployment descriptor. If you create any of
your own
custom tag
libraries, you should create taglib
elements for
them here as well.
The
welcome-file-list
element allows you to configure default
resources that should be used when a valid but partial URI is entered
for a web application. You can specify multiple welcome files, and
they will be used in the order in which they are listed.
Suppose we configured the
welcome-file-list
element for the Storefront
application as in Example 4-1.
Example 4-1. The welcome-file-list element for the Storefront application
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
This indicates that a request to the server for http://www.somehost.com/storefront, which is
the root of the Storefront application, should resolve to http://www.somehost.com/storefront/index.jsp.
This is beneficial because most containers would, by default, look
for index.html or index.htm instead. You can specify multiple
welcome-file
elements within the
welcome-file-list
. This might be helpful if, for
example, you deployed your application on various types of containers
and the first welcome-file
resource was not found
on the server. The container would continue to try to match the
welcome files up to the request URI until it found one on the server
and served that resource to the client. The order of the welcome file
entries in the deployment descriptor is used for the matching
process.
There should be no trailing or leading
“/” characters in the
welcome-file
element. If no welcome files are
declared for the web application or the URI entered by a client, the
web container may handle the request appropriately—for example,
it may return a 404 (File Not Found) error response or a directory
listing. It’s a good idea to configure a welcome
file for at least the root web application.
Because the
web containers don’t use
the servlet mappings for resources in the
welcome-file-list
, you can’t
directly set up a
welcome-file
element to use a Struts action.
However, there is an alternate way that allows you to achieve the same results. First, create a global forward in the Struts configuration file for the action that you would like to invoke:
<global-forwards> <forward name="welcome" path="viewsignin.do"/> </global-forwards>
Then create a JSP page called welcome.jsp (the name actually can be
anything you want) and use the Struts forward
tag
to forward to the global forward when the page is loaded. The
welcome.jsp
page only has to contain:
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html> <body> <logic:forward name="welcome"/> </body> </html>
You then need to add a welcome-file
element for
the welcome.jsp page:
<welcome-file-list> <welcome-file>welcome.jsp</welcome-file> </welcome-file-list>
When the container uses the welcome.jsp resource, it will automatically
forward to the forward named welcome
, which was
defined in the global-forwards
section. The
welcome
forward in turn invokes the
viewsignin.do
action and achieves the desired
result.
Although the Struts framework provides a
suitable error-handling mechanism, there are times that problems slip
through the exception-handling crack and users are shown a servlet or
JSP exception. To absolutely prevent this from happening, you should
use the error-page
element available to the web
application deployment descriptor. Example 4-2 shows
a partial web.xml
file that uses the
error-page
element to prevent users from seeing a
404 or a 500 (Internal Server) error.
Example 4-2. Using the error-page element
<web-app> <!-- Other elements go here --> <error-page> <error-code>404</error-code> <location>/common/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/common/500.jsp</location> </error-page> </web-app>
When an error status code is set in the response, the container
consults the list of error-page declarations for the web application.
If a match is found, the container returns the resource indicated by
the location
element. The value of the
location
element must begin with a
“/” character, and it must refer to
a resource within the web application.
If you need to refer to a resource outside of the web application,
you can use the HTML Refresh
meta tag. To do this,
refer to a static HTML document in the location
element that contains only the following line:
<meta http-equiv="Refresh" content="0;URL=http://www.somehost.com/404.jsp">
When the error occurs, the Refresh
meta tag will
reload immediately, but it will use the alternate URL provided. This
strategy also is a good way to allow users to refer to resources with
a static extension, such as .htm, but then
reload to a dynamic page, such as a JSP page.
Tip
For example, you can use this approach to show a “Still Processing” page. You might want to set the reload time to a value greater than zero. The URL can be a Struts action, and if the processing isn’t finished, it will just call the same page again. If processing has completed, it can forward to a completed page.
A servlet also can generate exceptions for which you can declare
error pages. Instead of specifying the error-code
element, you can specify a fully qualified Java class using the
exception-type
element. Servlets can throw the
following exceptions during processing:
RuntimeException
orError
ServletException
or subclassesIOException
or subclasses
The
Java exception class declared in the
exception-type
element must be one of these.
Example 4-3 illustrates how you would substitute the
exception-type
element for the error-code
.
Example 4-3. Using the exception-type instead of the error-code element
<web-app> <error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/common/system_error.jsp</location> </error-page> </web-app>
For the majority of this chapter, you have been shown partial deployment descriptors. This was done mainly to save space, but also so that we could ease our way into the various supported elements. Now it’s time to include a complete example of a web deployment descriptor. Example 4-4 shows the web deployment descriptor for the Storefront application.
Example 4-4. A complete web.xml file configured for Struts 1.1
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>storefront</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>storefront</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>404</error-code> <location>/common/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/common/500.jsp</location> </error-page> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> </web-app>
Get Programming Jakarta Struts now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.