Cover | Table of Contents | Colophon
http://struts.apache.org/acquiring.html and
deploy the example applications to your web container.http://struts.apache.org/acquiring.html and
deploy the example applications to your web container.http://jakarta.apache.org/tomcat. This recipe
assumes that you are using Tomcat 5. Set environment variables for
Struts and Tomcat, copy the Struts example WAR file to Tomcat, and
start Tomcat.C:\>set STRUTS_HOME=c:\jakarta-struts-1.1
C:\>set CATALINA_HOME=c:\tomcat5
C:\>copy %STRUTS_HOME%\webapps\struts-example.war %CATALINA_HOME%\webapps
1 file(s) copied.
C:\>%CATALINA_HOME%\bin\startup
Using CATALINA_BASE: c:\tomcat5
Using CATALINA_HOME: c:\tomcat5
Using CATALINA_TMPDIR: c:\tomcat5\temp
Using JAVA_HOME: c:\j2sdk1.4.2
%CATALINA_HOME%\bin\startup, starts Tomcat. On
Windows, you will see Tomcat startup in a separate terminal window.
The output in this terminal window displays information about the
applications deployed and the state of Tomcat:
Jun 22, 2004 12:23:34 AM org.apache.catalina.core.StandardHostDeployer install
INFO: Installing web application at context path /struts-example from URL file:c
:/tomcat5/webapps/struts-example
Jun 22, 2004 12:23:38 AM org.apache.struts.util.PropertyMessageResources <init>
INFO: Initializing, config='org.apache.struts.util.LocalStrings', returnNull=tru
e
Jun 22, 2004 12:23:38 AM org.apache.struts.util.PropertyMessageResources <init>
INFO: Initializing, config='org.apache.struts.action.ActionResources', returnNul
l=true
Jun 22, 2004 12:23:40 AM org.apache.struts.util.PropertyMessageResources <init>
INFO: Initializing, config='org.apache.struts.webapp.example.AlternateApplicatio
nResources', returnNull=true
Jun 22, 2004 12:23:40 AM org.apache.struts.util.PropertyMessageResources <init>
INFO: Initializing, config='org.apache.struts.webapp.example.ApplicationResource
s', returnNull=true
Jun 22, 2004 12:23:40 AM org.apache.struts.webapp.example.memory.MemoryDatabaseP
lugIn init
INFO: Initializing memory database plug in from '/WEB-INF/database.xml'
Jun 22, 2004 12:23:40 AM org.apache.struts.validator.ValidatorPlugIn initResourc
es
INFO: Loading validation rules file from '/WEB-INF/validator-rules.xml'
Jun 22, 2004 12:23:41 AM org.apache.struts.validator.ValidatorPlugIn initResourc
es
INFO: Loading validation rules file from '/WEB-INF/validation.xml'
...
Jun 22, 2004 12:23:44 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on port 80
Jun 22, 2004 12:23:45 AM org.apache.jk.common.ChannelSocket init
INFO: JK2: ajp13 listening on /0.0.0.0:8009
Jun 22, 2004 12:23:45 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=20/50 config=c:\tomcat5\conf\jk2.properties
|
Struts 1.0.2 Taglib URI
|
Struts 1.1 Taglib URI
|
|---|---|
|
http://jakarta.apache.org/struts/tags-bean-1.0.2
|
http://jakarta.apache.org/struts/tags-bean
|
|
http://jakarta.apache.org/struts/tags-html-1.0.2
|
http://jakarta.apache.org/struts/tags-html |
http://struts.apache.org/acquiring.html.taglib directives
in your JSP pages, change these to use the new URIs shown in Table 1-4.|
Struts 1.1 Taglib URI
|
Struts 1.2.4 Taglib URI
|
|---|---|
|
http://jakarta.apache.org/struts/tags-bean
|
http://struts.apache.org/tags-bean
|
|
http://jakarta.apache.org/struts/tags-html
|
http://struts.apache.org/tags-html
|
|
http://jakarta.apache.org/struts/tags-logic
|
http://struts.apache.org/tags-logic
|
|
http://jakarta.apache.org/struts/tags-template |
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Simple Calculator</title>
</head>
<body>
<a href="get_input.jsp">Calculator</a>
</body>
</html>form-bean
name, or class name.http://www.jamesholmes.com, provides a
graphical editor for the Struts
(struts-config.xml),
Validator
(validation.xml and
validator-rules.xml), and Tiles
(tiles-defs.xml) configuration files. Instead of
hand-editing these files, you use the Swing-based editor provided by
Struts Console. In addition to reducing the typos, Struts Console
gives you a birds-eye view of these files for easier browsing. You
will find this feature invaluable when your configuration files start
to get large.struts-example application.
http://ant.apache.org) build script and use
Ant (or your IDE's Ant integration) to compile,
test, package, and deploy your application. Example 1-8 is a boilerplate Ant build file that can
compile, build, and deploy a Struts application.<project name="jsc-ch01-r02" default="dist" basedir=".">
<description>
Jakarta Struts Cookbook - Ant Template
</description>
<!-- Enable access to environment variables -->
<property environment="env"/>
<!-- Set to use JDK 1.4 -->
<property name="build.compiler" value="javac1.4"/>
<!-- set global properties for this build -->
<property name="src.dir" location="src"/>
<property name="build.dir" location="build"/>
<property name="dist.dir" location="dist"/>
<property name="server.dir" location="${env.CATALINA_HOME}"/>
<property name="servlet.jar"
location="${server.dir}/common/lib/servlet-api.jar"/>
<property name="jsp.jar" location="${server.dir}/common/lib/jsp-api.jar"/>
<property name="struts.dist.dir" location="c:/jakarta-struts-1.1/lib"/>
<!-- Struts -->
<fileset id="struts.lib.files" dir="${struts.dist.dir}">
<include name="**/*.jar"/>
</fileset>
<path id="struts.classpath">
<fileset refid="struts.lib.files"/>
</path>
<path id="project.class.path">
<pathelement location="${servlet.jar}"/>
<pathelement location="${jsp.jar}"/>
<path refid="struts.classpath"/>
</path>
<!-- Deployment Properties -->
<property name="deploy.dir" location="${server.dir}/webapps"/>
<target name="clean"
description="clean up" >
<!-- Delete the ${build.dir} and ${dist.dir} directory trees -->
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="init">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build.dir}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src.dir} into ${build.dir} -->
<javac srcdir="${src.dir}" destdir="${build.dir}" debug="on">
<classpath>
<path refid="project.class.path"/>
</classpath>
</javac>
<copy todir="${build.dir}">
<fileset dir="${src.dir}">
<include name="**/*.properties"/>
</fileset>
</copy>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist.dir}"/>
<!-- Copy the build dir to WEB-INF/classes -->
<mkdir dir="web/WEB-INF/classes"/>
<copy todir="web/WEB-INF/classes">
<fileset dir="${build.dir}"/>
</copy>
<!-- Put everything in ${build} into the war file -->
<war destfile="${dist.dir}/${ant.project.name}.war"
webxml="web/WEB-INF/web.xml">
<fileset dir="web" excludes="**/web.xml"/>
<webinf dir="web/WEB-INF">
<include name="*.xml"/>
<exclude name="web.xml"/>
</webinf>
<lib dir="web/WEB-INF/lib">
<include name="${struts.dist.dir}/**/*.jar"/>
<include name="${struts.dist.dir}/**/*.tld"/>
</lib>
<classes dir="build"/>
</war>
</target>
<!-- Deploy the application by copying it to the deployment directory -->
<target name="deploy" depends="dist"
description="deploy to server" >
<unjar src="${dist.dir}/${ant.project.name}.war"
dest="${deploy.dir}/${ant.project.name}"/>
</target>
</project>Action
or ActionForm, you have to make the corresponding
changes to Struts configuration files.
action elements
form-bean elements
ActionForms, XDoclet can generate the
ActionForm Java
source code.http://xdoclet.sourceforge.net.
Follow the installation instructions
provided to install it. You will need to have Ant installed as well.org.apache.struts.action.PlugIn interface and
specify the plug-in element in the
struts-config.xml. The following XML fragment
shows a plug-in declaration and a nested
set-property element for setting a custom
property:<plug-in className="com.oreilly.strutsckbk.CustomPlugin" >
<set-property property="customData"
value="Hello from the plugin"/>
</plug-in>
PlugIn
interface you can use to create custom services that are initialized
on application startup. The Java source for the
PlugIn interface is shown in Example 2-1. (For clarity, the JavaDoc documentation has
been removed from this listing.)org.apache.struts.action.PlugIn interface and
specify the plug-in element in the
struts-config.xml. The following XML fragment
shows a plug-in declaration and a nested
set-property element for setting a custom
property:<plug-in className="com.oreilly.strutsckbk.CustomPlugin" >
<set-property property="customData"
value="Hello from the plugin"/>
</plug-in>
PlugIn
interface you can use to create custom services that are initialized
on application startup. The Java source for the
PlugIn interface is shown in Example 2-1. (For clarity, the JavaDoc documentation has
been removed from this listing.)package org.apache.struts.action;
import javax.servlet.ServletException;
import org.apache.struts.config.ModuleConfig;
public interface PlugIn {
public void destroy( );
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException;
}
init() and destroy( ), are called during the
lifecycle of the plug-in. Struts calls the init( )
method after it instantiates the plug-in on startup of the
ActionServlet. Struts calls the destroy() method when the ActionServlet is
destroyed, usually on shutdown of the application server. At first,
this plug-in feature may seem simplistic and limited. However, by
utilizing another feature of Struts, the
set-property
element, you can pass ad hoc information to the plug-in. This
capability enhances the flexibility of these classes.taglib elements to
the web.xml file every time you want to use a
new tag library.taglib directives
that refer to the absolute URIs for the tag libraries you are using.
Example 2-4 (taglibs.inc.jsp)
shows a JSP file containing the taglib
declarations for the Struts bean,
html, and logic tag libraries
as well as the JSTL core and formatting tag libraries.<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
include directive:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- start taglib -->
<%@ include file="/includes/taglibs.inc.jsp" %>
<!-- end taglib -->
<html:html>
<body>
...
taglib directive, you aren't
required to enter a corresponding taglib element
in the application's web.xml
file.taglib directive on the
JSP
page and you don't have to specify
taglib elements in the
web.xml.taglib descriptors used for a
Struts application:<!-- Struts Tag Library Descriptors --> <taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-html</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-logic</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-nested</taglib-uri> <taglib-location>/WEB-INF/struts-nested.tld</taglib-location> </taglib>
public static fields
defined in Java classes—on a JSP page.bind tag provided by the Jakarta Taglibs
unstandard
tag library to create a JSTL variable containing the value of
the constant field:<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
<un:bind var="constantValue"
type="com.foo.MyClass"
field="SOME_CONSTANT"/>
<bean:write name="constantValue"/>
public
static fields (constants). Unfortunately, neither
Struts nor JSP provide a means to access these constants from a JSP
page without resorting to JSP scriptlet like the following:<%= com.foo.MyClass.SOME_CONSTANT %>
<% . . . %>) and runtime
expressions (<%= . . . %>) place Java code
directly onto a JSP page. They are not inherently evil, but they can
lead your development down a slippery slope by turning your JSP pages
into a tangled brittle mass of intermixed HTML, JSP, and Java code.
Find solutions that don't require you to use
scriptlets. You'll find—particularly with the
introduction of JSTL—that you can always find a way around the
dreaded scriptlet.un:bind
tag. This tag is part of the unstandard tag
library, part of the Jakarta Taglibs distribution. The
unstandard tag library contains custom JSP tags
that have been or are being considered for use in the
standard tab library. The
standard tag library is the Jakarta Taglibs
implementation of the JSTL specification.config
initialization parameter of the ActionServlet in
the web.xml file as shown in Example 2-9.<servlet>
<servlet-name>action</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,
/WEB-INF/struts-config-2.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
ActionServlet is loaded, Struts will
merge the results of the specified configuration files into a single
in-memory configuration.action
elements numbering in the hundreds. Combine this with the use of a
locking source control system, and soon you will have developers in
constant contention for the same file.config
ActionServlet initialization parameter in your
web.xml file. You specify the files as a
comma-separated list of file paths. At runtime, the files are merged
in memory into a single configuration set. If duplicate elements
exist—for example, a form bean declaration with the same value
for the ActionServlet in the web.xml,
as shown in Example 2-11.<!-- Action Servlet Configuration -->
<servlet>
<servlet-name>action</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>config/module1</param-name>
<param-value>/WEB-INF/struts-config-module1.xml</param-value>
</init-param>
<init-param>
<param-name>config/module2</param-name>
<param-value>/WEB-INF/struts-config-module2.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
config/ in the
initialization parameter for the Struts'
ActionServlet. In Example 2-11,
three modules are defined. The first init-param
element defines the default module. The second
and third init-parammessage-resources
element for each file in your struts-config.xml
file:<message-resources parameter="com.oreilly.strutsckbk.MessageResources"/> <message-resources parameter="com.oreilly.strutsckbk.LabelResources" key="labels"> </message-resources> <message-resources parameter="com.oreilly.strutsckbk.HeaderResources" key="headers"> </message-resources>
ResourceBundle.message-resources
element. The parameter attribute identifies the
classpath-relative name of the properties file. You derive the value
for this attribute by replacing the path separator in the
file's path with a dot
(".") and removing the
.properties extension from the filename. For
example, if the properties file was located in
/WEB-INF/classes/com/oreilly/strutsckbk/MessageResources.properties,
you would set up the message resources element as follows:<message-resources parameter="com.oreilly.strutsckbk.MessageResources"/>
bean:message tag.http://prdownloads.sourceforge.net/struts/ojb-message-resources.zip?download.CREATE TABLE ojb_dlist ( ID int NOT NULL default '0', SIZE_ int default NULL, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_dlist_entries ( ID int NOT NULL default '0', DLIST_ID int NOT NULL default '0', POSITION_ int default NULL, OID_ longblob, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_dmap ( ID int NOT NULL default '0', SIZE_ int default NULL, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_dmap_entries ( ID int NOT NULL default '0', DMAP_ID int NOT NULL default '0', KEY_OID longblob, VALUE_OID longblob, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_dset ( ID int NOT NULL default '0', SIZE_ int default NULL, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_dset_entries ( ID int NOT NULL default '0', DLIST_ID int NOT NULL default '0', POSITION_ int default NULL, OID_ longblob, PRIMARY KEY (ID) ) TYPE=MyISAM; CREATE TABLE ojb_hl_seq ( TABLENAME varchar(175) NOT NULL default '', FIELDNAME varchar(70) NOT NULL default '', MAX_KEY int default NULL, GRAB_SIZE int default NULL, PRIMARY KEY (TABLENAME,FIELDNAME) ) TYPE=MyISAM; CREATE TABLE ojb_lockentry ( OID_ varchar(250) NOT NULL default '', TX_ID varchar(50) NOT NULL default '', TIMESTAMP_ decimal(10,0) default NULL, ISOLATIONLEVEL int default NULL, LOCKTYPE int default NULL, PRIMARY KEY (OID_,TX_ID) ) TYPE=MyISAM; CREATE TABLE ojb_nrm ( NAME varchar(250) NOT NULL default '', OID_ longblob, PRIMARY KEY (NAME) ) TYPE=MyISAM; CREATE TABLE ojb_seq ( TABLENAME varchar(175) NOT NULL default '', FIELDNAME varchar(70) NOT NULL default '', LAST_NUM int default NULL, PRIMARY KEY (TABLENAME,FIELDNAME) ) TYPE=MyISAM;
action element in your
struts-config.xml
file; forwarding any requests to the disabled action to an
"under construction" page.ActionMapping
extension (as shown in Example 2-16) that provides a
boolean property indicating if the action is disabled or not.import org.apache.struts.action.ActionMapping;
public class DisablingActionMapping extends ActionMapping {
private String disabled;
private boolean actionDisabled = false;
public String getDisabled( ) {
return disabled;
}
public void setDisabled(String disabled) {
this.disabled = disabled;
actionDisabled = new Boolean(disabled).booleanValue( );
}
public boolean isActionDisabled( ) {
return actionDisabled;
}
}
disabled property to true if an
action is to be disabled:<action-mappings type="com.oreilly.strutsckbk.DisablingActionMapping">
<!-- Edit mail subscription -->
<action path="/editSubscription"
type="org.apache.struts.webapp.example.EditSubscriptionAction"
attribute="subscriptionForm"
scope="request"
validate="false">
<set-property property="disabled" value="true"/>
<forward name="failure" path="/mainMenu.jsp"/>
<forward name="success" path="/subscription.jsp"/>
</action>
RequestProcessor, such as the
one shown in Example 2-17, that handles the
DisablingActionMapping.import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.RequestProcessor;
public class CustomRequestProcessor extends RequestProcessor {
protected ActionForward processActionPerform(HttpServletRequest request,
HttpServletResponse response, Action action,ActionForm form,
ActionMapping mapping) throws IOException, ServletException {
ActionForward forward = null;
if (!(mapping instanceof DisablingActionMapping)) {
forward = super.processActionPerform( request, response,
action, form, mapping);
}
else {
DisablingActionMapping customMapping =
(DisablingActionMapping) mapping;
if (customMapping.isActionDisabled( )) {
forward = customMapping.findForward("underConstruction");
}
else {
forward = super.processActionPerform( request, response,
action, form, mapping);
}
}
return forward;
}
}http://jakarta.apache.org/taglibs. Copy the
http://jakarta.apache.org/taglibs. Copy the
jstl.jar and standard.jar
files from the lib folder into your applications
WEB-INF/lib folder. Then copy the
c.tld, fmt.tld,
sql.tld, and x.tld files
from the tlds folder into your applications
WEB-INF/lib folder.taglib directives on JSP pages
where you want to use JSTL:<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
Tag library
|
JSTL 1.0 Taglib URI
|
JSTL 1.1 Taglib URI
|
|---|---|---|
|
Core
|
http://java.sun.com/jstl/core
|
http://java.sun.com/jsp/jstl/core
|
|
Formatting
|
http://java.sun.com/jstl/fmt
|
http://java.sun.com/jsp/jstl/fmt
|
|
SQL
|
http://java.sun.com/jstl/sql
|
taglib directives
on JSP pages where you want to use expressions:<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el"
prefix="html-el" %>
taglib URIs.|
Tag library
|
Struts-EL Taglib URI (1.1)
|
Struts-EL Taglib URI (1.2)
|
|---|---|---|
|
html-el
|
http://jakarta.apache.org/struts/tags-html-el
|
http://struts.apache.org/tags-html-el
|
|
bean-el
|
http://jakarta.apache.org/struts/tags-bean-el
|
http://struts.apache.org/tags-bean-el
|
|
logic-el
|
http://jakarta.apache.org/struts/tags-logic-el
|