Programming Jakarta Struts, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming Jakarta Struts, 2nd Edition [Electronic resources] - نسخه متنی

Chuck Cavaness

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








4.5 Configuring the web.xml File for Struts


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.


4.5.1 Mapping the Struts ActionServlet


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.


You need to configure only a single ActionServlet,
regardless of the number of application modules 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.

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 element
specifies 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.


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.


4.5.1.1 Mapping requests to servlets

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.


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:

  1. The container attempts to locate an exact match of the request path
    to the path of a servlet.

  2. The container recursively tries to match the longest path prefix. The
    servlet that contains the longest match, if any, is selected.

  3. If the URL path contains an extensionfor example,
    .dothe 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 (.).

  4. 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 web container uses case-sensitive string comparisons when
checking for a match.

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.


4.5.2 Specifying Multiple Application Modules


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.


4.5.3 Declaring the Initialization Parameters


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


config


A context-relative path to the default Struts configuration file. The
default value is /WEB-INF/struts-config.xml, which
serves as the default application. Starting with Struts 1.1, you can
specify a comma-separated list of configuration files for this
paramter.


config/sub1


Specify additional application modules by using the value
config/ and the prefix of the module. In this
example, the init-param name would be
config/module1, and the value might be
WEB-INF/struts-sub1-config.xml. This tells the
controller to load the application module mod1
from the additional Struts configuration file. You can declare as
many application modules as you need.


convertNull


Force simulation of the Struts 1.0 behavior when populating forms. If
set to true, the numeric Java wrapper class types such as
java.lang.Integer will default to null rather than
0. The default is false.


validating


A validating XML parser is used to process the configuration file.
This is strongly recommended. The default value is true.


There are several initialization parameters that have been deprecated
in Version 1.1. Most of them are now supported through the Struts
configuration file, which is discussed later in the chapter.


4.5.4 Using Multiple Struts Configuration Files


We've briefly
mentioned using multiple application modules with Struts 1.1, but now
you can use multiple configuration files as well. This is possible
because the previously monolithic Struts configuration file has now
been separated into individual XML files, making it possible to
declare each them with the config initialization
parameter. This is helpful because no single Struts configuration
file now contends for resources during development. Using multiple
files also makes is easier to support optional functionality. If, for
example, you don't need to deploy certain Struts
actions or other configuration elements, you can group them into a
single file and remove all of them at once by removing that file from
the list in web.xml. The following
init-param fragment shows how to include more than
one Struts configuration file:

  <init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml,/WEB-INF/other-struts-config.xml
</param-value>
</init-param>

You can declare as many configuration files as needed.


4.5.5 Configuring the Tag Libraries


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.


4.5.6 Setting Up the Welcome File List


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 indexl or index
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 appropriatelyfor 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.


4.5.6.1 Using a Struts action in the welcome file list

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>

Containers using the welcome.jsp resource 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.


4.5.7 Configuring Error Handling in web.xml


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 , but then
reload to a dynamic page, such as a JSP page.


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 actionif 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 or Error

  • ServletException or subclasses

  • IOException 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>
<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>


    / 181