husted 01/02/11 14:57:00
Modified: src/doc/userGuide building_view.xml building_model.xml
Log:
Change file format to Unix to help with single spacing <pre> blocks.
Revision Changes Path
1.16 +614 -533 jakarta-struts/src/doc/userGuide/building_view.xml
Index: building_view.xml
===================================================================
RCS file: /home/cvs/jakarta-struts/src/doc/userGuide/building_view.xml,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- building_view.xml 2001/02/11 21:39:20 1.15
+++ building_view.xml 2001/02/11 22:56:59 1.16
@@ -1,533 +1,614 @@
-<?xml version="1.0"?>
-<document url="./building_view.xml">
-
- <properties>
- <author>Craig R. McClanahan</author>
- <author>Mike Schachter</author>
- <author>Ted Husted</author>
- <title>The Struts User's Guide - Building View Components</title>
- </properties>
-
- <body>
- <chapter name="3. Building View Components" href="building_view">
-
- <section name="3.1 Overview" href="overview">
-
- <p>
- This chapter focuses on the task of building the <i>View</i> components
- of the application, which will primarily be created using JavaServer Pages
- (JSP) technology. In particular, Struts provides support for building
- internationalized applications, as well as for interacting with input
forms.
- Several other topics related to the View components are briefly discussed.
- </p>
-
- </section>
-
- <section name="3.2 Internationalized Messages" href="i18n">
-
- <p>
- A few years ago, application developers could count on having to support
- only residents of their own country, who are used to only one (or sometimes
- two) languages, and one way to represent numeric quantities like dates,
- numbers, and monetary values. However, the explosion of application
- development based on web technologies, as well as the deployment of such
- applications on the Internet and other broadly accessible networks, have
- rendered national boundaries invisible in many cases. This has translated
- (if you will pardon the pun) into a need for applications to support
- <i>internationalization</i> (often called "i18n" because 18 is the number
of
- letters in between the "i" and the "n") and <i>localization</i>.
- </p>
-
- <p>
- Struts builds upon the Java platform to provide assistance
- for building internationalized and localized applications. The key
concepts
- to become familiar with are:
- </p>
-
- <ul>
- <li><b>Locale</b> - The fundamental Java class that supports
- internationalization is <code>java.util.Locale</code>. Each
- <code>Locale</code> represents a particular choice of country and
- language (plus an optional language variant), and also a set of
- formatting assumptions for things like numbers and dates.</li>
- <li><b>ResourceBundle</b> - The <code>java.util.ResourceBundle</code> class
- provides the fundmental tools for supporting messages in multiple
- languages. See the Javadocs for the <code>ResourceBundle</code> class,
- and the information on Internationalization in the documentation bundle
- for your JDK release, for more information.</li>
- <li><b>PropertyResourceBundle</b> - One of the standard implementations of
- <code>ResourceBundle</code> allows you to define resources using the
- same "name=value" syntax used to initialize properties files. This is
- very convenient for preparing resource bundles with messages that are
- used in a web application, because these messages are generally text
- oriented.</li>
- <li><b>MessageFormat</b> - The <code>java.text.MessageFormat</code> class
- allows you to replace portions of a message string (in this case,
- one retrieved from a resource bundle) with arguments specified at
- run time. This is useful in cases where you are creating a sentence,
- but the words would appear in a different order in different languages.
- The placeholder string <code>{0}</code> in the message is replaced by
- the first runtime argument, <code>{1}</code> is replaced by the second
- argument, and so on.</li>
- <li><b>MessageResources</b> - The Struts class
- <code><a
href="api/org/apache/struts/util/MessageResources.html">org.apache.struts.util.MessageResources</a></code>
lets you treat
- a set of resource bundles like a database, and allows you to request
- a particular message string for a particular Locale (normally one
- associated with the current user) instead of for the default Locale
- the server itself is running in.</li>
- </ul>
-
- <p>
- For an internationalized application, follow the steps described in
- the Internationalization document in the JDK documentation bundle for your
- platform to create a properties file containing the messages for each
- language. An example will illustrate this further:
- </p>
-
- <p>
- Assume that your source code is created in package
- <code>com.mycompany.mypackage</code>, so it is stored in a directory
- (relative to your source directory) named
- <code>com/mycompany/mypackage</code>. To create a resource bundle called
- <code>com.mycompany.mypackage.MyResources</code>, you would create the
- following files in the <code>com/mycompany/mypackage</code> directory:
- </p>
-
- <ul>
- <li><b>MyResources.properties</b> - Contains the messages in the default
- language for your server. If your default language is English, you
- might have an entry like this:
- <code>prompt.hello=Hello</code></li>
- <li><b>MyResources_xx.properties</b> - Contains the same messages in the
- language whose ISO language code is "xx" (See the ResourceBundle
- Javadoc page for a link to the current list). For a French version
- of the message shown above, you would have this entry:
- <code>prompt.hello=Bonjour</code>
- You can have resource bundle files for as many languages as you
need.</li>
- </ul>
-
- <p>
- When you configue the controller servlet in the web application
- deployment descriptor, one of the things you will need to define in
- an initialization parameter is the base name of the resource bundle
- for the application. In the case described above, it would be
- <code>com.mycompany.mypackage.MyResources</code>.
- </p>
-<pre>
-<servlet><br/> <servlet-name>action</servlet-name><br/>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class><br/>
<init-param><br/> <param-name>application</param-name><br/>
<param-value>com.mycompany.mypackage.MyResources</param-value><br/>
</init-param><br/> <.../><br/></servlet></pre>
-
- <p>
- The important thing is for the resource bundle to be found on the
- class path for your application. Another approach is to store
- the <code>MyResources.properties</code> file in your application's
- class folder. You can then simply specify "myResources" as the
- application value.
- </p>
- </section>
-
- <section name="3.3 Forms and FormBean Interactions" href="form_beans">
-
- <p>
- At one time or another, most web developers have built forms using
- the standard capabilities of HTML, such as the <code><input></code>
- tag. Users have come to expect interactive applications to have certain
- behaviors, and one of these expectations relates to error handling -- if
- the user makes an error, the application should allow them to fix just what
- needs to be changed -- without having to re-enter any of the rest of the
- information on the current page or form.
- </p>
-
- <p>
- Fulfilling this expectation is tedious and cumbersome when coding with
- standard HTML and JSP pages. For example, an input element for a
- <code>username</code> field might look like this (in JSP):
- </p>
-
-<pre>
-<input type="text" name="username"<br/> value="<%=
loginBean.getUsername() %>"/></pre>
-
- <p>
- which is difficult to type correctly, confuses HTML developers who are
- not knowledgeable about programming concepts, and can cause problems with
- HTML editors. Instead, Struts provides a comprehensive facility for
- building forms, based on the Custom Tag Library facility of JSP 1.1.
- The case above would be rendered like this using Struts:
- </p>
-
-<pre>
-<html:text property="username"/></pre>
-
- <p>
- with no need to explicitly refer to the JavaBean from which the initial
- value is retrieved. That is handled automatically by the framework.
- </p>
- <p>
- HTML forms are sometimes used to upload other files. Most browsers
- support this through a <input type="file"> element, that generates
- a file browse button, but it's up to the developer to handle the incoming
- files. Struts handles these "multipart" forms in a way identical to
- building normal forms. In the next section, we will cover using Struts to
- create a simple login form, and also a simple mulitpart form.
- </p>
-
- <section name="3.3.1 Building Forms With Struts" href="forms">
-
- <p>
- A complete example of a login form will illustrate how Struts
- makes dealing with forms much less painful than using straight HTML
- and standard JSP facilities. Consider the following page (based on the
- example application included with Struts) named <code>logon.jsp</code>:
- </p>
-<hr/>
-<pre>
-<%@ page language="java" %><br/><%@ taglib
uri="/WEB-INF/struts-html.tld"<br/> prefix="html" %><br/><%@ taglib
uri="/WEB-INF/struts-bean.tld"<br/> prefix="bean" %>
-<html:html><br/><head><br/><title><br/> <bean:message
key="logon.title"/><br/></title><br/>
-<body bgcolor="white"><br/><html:errors/><br/>
-<html:form name="logonForm" action="logon.do"<br/>
type="org.apache.struts.example.LogonForm"><br/><table border="0"
width="100%"><br/>
- <tr><br/> <th align="right"><br/> <html:message
key="prompt.username"/><br/> </th><br/> <td align="left"><br/>
<html:text property="username"<br/> size="16"/><br/>
</td><br/> </tr>
- <tr><br/> <th align="right"><br/> <html:message
key="prompt.password"/><br/> </th><br/> <td align="left"><br/>
<html:password property="password"<br/>
size="16"/><br/> </td><br/> </tr>
- <tr><br/>
- <td align="right"><br/> <struts:submit><br/>
<bean:message key="button.submit"/><br/> </struts:submit><br/>
</td><br/> <td align="right"><br/> <html:reset><br/>
<bean:message key="button.reset"/><br/> </html:reset><br/>
</td><br/> </tr><br/></table><br/></html:form>
-</body><br/></html:html></pre>
-<hr/>
- <p>
- The following items illustrate the key features of form handling in
Struts,
- based on this example:
- </p>
-
- <ul>
- <li>The <code>taglib</code> directive tells the JSP page compiler where
to
- find the <i>tag library descriptor</i> for the Struts tag library.
In
- this case, we are using <code>bean</code> as the prefix that
identifies
- tags from the struts-bean library, and "html" as the prefix that
identifies
- tags from the struts-html library. Any desired prefix can be
used.</li>
- <li>This page uses several occurrences of the
- message tag to look up internationalized
- message strings from a <code>MessageResources</code> object
containing
- all the resources for this application. For this page to work, the
- following message keys must be defined in these resources:
- <ul>
- <li><b>logon.title</b> - Title of the logon page</li>
- <li><b>prompt.username</b> - A "Username:" prompt string</li>
- <li><b>prompt.password</b> - A "Password:" prompt string</li>
- <li><b>button.submit</b> - "Submit" for the button label</li>
- <li><b>button.reset</b> - "Reset" for the button label</li>
- </ul>
- When the user logs on, the application can store a
<code>Locale</code>
- object in the user's session. This <code>Locale</code> will be used
- to select messages in the appropriate language. This makes it easy
to
- implement giving the user an option to switch languages -- simply
change
- the stored <code>Locale</code> object, and all messages are switched
- automatically.</li>
- <li>The errors tag displays any error
- messages that have been stored by a business logic component, or
nothing
- if no errors have been stored. This tag will be described further
- below.</li>
- <li>The form tag renders an HTML
- <code><form></code> element, based on the specified attributes.
- It also associates all of the fields within this form with a session
- scoped FormBean that is stored under the key <code>logonForm</code>.
- This bean is used to provide initial values for all of the input
- fields that have names matching the property names of the bean.
- If an appropriate bean is not found, a new one will be created
- automatically, using the specified Java class name.
- <li>The form bean can also be specified in the Struts configuration
file,
- in which case the Name and Type can be omitted
- here. See "<a href="building_controller.html#config">The Action
Mappings
- Configuration File</a>" for details.)</li>
- </li>
- <li>The text tag renders an HTML
- <code><input></code> element of type "text". In this case,
- the number of character positions to occupy on the browser's screen
- has been specified as well. When this page is executed, the current
- value of the <code>username</code> property of the corresponding bean
- (that is, the value returned by <code>getUsername()</code>).</li>
- <li>The password tag is used similarly.
- The difference is that the browser will echo asterisk characters,
- instead of the input value, as the user types their password.</li>.
- <li>The submit and
- reset tags generate the corresponding
- buttons at the bottom of the form. The text labels for each button
- are created using message tags,
- as with the prompts, so that these values are internationalized.</li>
- </ul>
-
- <p>
- Handling multipart forms is also easy. Obviously when you create a
multipart
- form you're creating a form that has at least one input of type "file".
The first step to
- creating a multipart form is to utilize the struts-html taglib to create
the presentation
- page:
- </p>
-
-<hr/>
-<pre>
-<%@page language="java"><br/><%@taglib uri="/WEB-INF/struts-html.tld"<br/>
prefix="html"><br/>
-<html:form action="uploadAction.do"><br/> Please Input Text:<br/>
<html:text property="myText"><br/><br/> Please Input The File You Wish to
Upload:<br/><br/> <html:file property="myFile"><br /><br/> <html:submit
/><br/></html:form></pre>
-<hr/>
- <p>
- The next step is to create your ActionForm bean:
- </p>
-
-<hr/>
-<pre>
-import javax.servlet.http.HttpServletRequest;<br/>import
javax.servlet.http.HttpServletResponse;<br/>import
org.apache.struts.action.ActionForm;<br/>import
org.apache.struts.action.ActionMapping;<br/>import org.apache.struts.upload.FormFile;
-public class UploadForm extends ActionForm {<br/> protected String myText;<br/>
protected FormFile myFile;
- public void setMyText(String text) {<br/> myText = text;<br/> }
- public String getMyText() {<br/> return myText;<br/> }
- public void setMyFile(FormFile file) {<br/> myFile = file;<br/> }
- public FormFile getMyFile() {<br/> return myFile;<br/> }<br/>}</pre>
-<hr/>
- <p>
- Look at the <a href="../api/index.html">javadocs</a> for FormFile to see
the
- methods it exposes to manipulate files in file uploading. Also look at
the
- javadocs for ActionServlet and ActionMapping for the various parameters
- you can specify to change how files are uploaded. Basically in your
- peform() method in your action class you would call <code>((UploadForm)
form).getMyFile()</code>
- to retrieve the FormFile and do what you want with it.
- </p>
-
- </section>
-
- <section name="3.3.2 Input Field Types Supported" href="form_input">
-
- <p>
- Struts defines HTML tags for all of the following types of input fields,
- with hyperlinks to the corresponding reference information.
- </p>
-
- <ul>
- <li><a href="../struts-html.html#checkbox">checkboxes</a></li>
- <li><a href="../struts-html.html#hidden">hidden</a> fields</li>
- <li><a href="../struts-html.html#password">password</a> input
fields</li>
- <li><a href="../struts-html.html#radio">radio</a> buttons</li>
- <li><a href="../struts-html.html#reset">reset</a> buttons</li>
- <li><a href="../struts-html.html#select">select</a> lists with
embedded</li>
- <li><a href="../struts-html.html#option">options</a></li>
- <li><a href="../struts-html.html#submit">submit</a> buttons</li>
- <li><a href="../struts-html.html#text">text</a> input fields</li>
- <li><a href="../struts-html.html#textarea">textareas</a></li>
- </ul>
-
- <p>
- In every
- case, a field tag must be nested within a <code>form</code> tag, so that
- the field knows what bean to use for initializing displayed values.
- </p>
- </section>
-
- <section name="3.3.3 Other Useful Presentation Tags"
href="presentation_tags">
-
- <p>
- There are several tags useful for creating presentations, consult the
documentation
- on each specific tag library, along with the Tag Developers Guides, for
more
- information:
- </p>
-
- <ul>
-
- <li>[logic] <a href="../struts-logic.html#iterate">iterate</a> repeats
its tag body once
- for each element of a specified collection (which can be an
Enumeration,
- a Hashtable, a Vector, or an array of objects).</li>
- <li>[logic] <a href="../struts-logic.html#present">present</a> depending
on which attribute
- is specified, this tag checks the current request, and evaluates the
nested
- body content of this tag only if the specified value is present. Only
one of
- the attributes may be used in one occurrence of this tag, unless you
use the
- property attribute, in which case the name attribute is also
required. The
- attributes include cookie, header, name, parameter, property, role,
scope,
- and user.
- </li>
- <li>[logic] <a href="../struts-logic.html#notPresent">notPresent</a> the
companion tag to
- present, notPresent provides the same functionality when the
specified attribute
- is not present.</li>
- <li>[html] <a href="../struts-html.html#link">link</a> generates a HTML
<a> element
- as an anchor definition or a hyperlink to the specified URL, and
automatically
- applies URL encoding to maintain session state in the absence of
- cookie support.</li>
- <li>[html] <a href="../struts-html.html#img">img</a> generates a HTML
<img> element
- with the ability to dynamically modify the URLs specified by the
"src" and
- "lowsrc" attributes in the same manner that <html:link> can.
- </li>
- <li>[bean] <a href="../struts-bean.html#parameter">parameter</a>
retrieves the value of the
- specified request parameter, and defines the result as a page scope
attribute of
- type String or String[].</li>
- </ul>
-
- </section>
-
- <section name="3.3.4 Automatic Form Validation" href="form_validation">
-
- <p>
- In addition to the form and bean interactions described above, Struts
- offers an additional facility to validate the input fields it has
received.
- To utilize this feature, override the following method in your ActionForm
- class:
- </p>
-
-<pre>public ActionErrors<br/> validate(ActionMapping mapping,<br/>
HttpServletRequest request);</pre>
-
- <p>
- The validate() method is called by the controller servlet after the bean
- properties have been populated, but before the corresponding action
class's
- <code>perform()</code> method is invoked. The <code>validate()</code>
method
- has the following options:
- </p>
-
- <ul>
- <li>Perform the appropriate validations and find no problems -- Return
either
- <code>null</code> or a zero-length ActionErrors instance, and the
controller
- servlet will proceed to call the <code>perform()</code> method of the
- appropriate <code>Action</code> class.</li>
- <li>Perform the appropriate validations and find problems -- Return an
ActionErrors
- instance containing <code>ActionError</code>'s, which are classes
that contain
- the error message keys (into the application's
- <code>MessageResources</code> bundle) that should be displayed. The
- controller servlet will store this array as a request attribute
suitable
- for use by the <code><html:errors></code> tag, and will forward
- control back to the input form (identified by the
<code>inputForm</code>
- property for this <code>ActionMapping</code>).</li>
- </ul>
-
- <p>
- As mentioned earlier, this feature is entirely optional. The default
implementation
- of the validate() method returns <code>null</code>, and the controller
servlet
- will assume that any required validation is done by the action class.
- </p>
- <p>
- One common approach is to perform simple validations using the validate()
method, and
- also provide further "business logic" validation as part of your Action
object.
- </p>
-
- </section>
- </section>
-
- <section name="3.4 Other Presentation Techniques" href="other_presentations">
-
- <p>
- Although the look and feel of your application can be completely
constructed
- based on the standard capabilities of JSP and the Struts custom tag
library,
- you should consider employing other techniques that will improve component
- reuse, reduce maintenance efforts, and/or reduce errors. Several options
- are discussed in the following sections.
- </p>
-
- <section name="3.4.1 Application-Specific Custom Tags" href="custom_tags">
-
- <p>
- Beyond using the custom tags provided by the Struts library, it is easy
- to create tags that are specific to the application you are building, to
- assist in creating the user interface. The example application included
with
- Struts illustrates this principle by creating the following tags unique
to
- the implementation of this application:
- </p>
-
- <ul>
- <li><b>checkLogon</b> - Checks for the existence of a particular session
- object, and forwards control to the logon page if it is missing.
This is
- used to catch cases where a user has bookmarked a page in the middle
of
- your application and tries to bypass logging on, or if the user's
session
- has been timed out.</li>
- <li><b>linkSubscription</b> - Generates a hyperlink to a details page
- for a Subscription, which passes the required primary key values as
- request attributes. This is used when listing the subscriptions
associated
- with a user, and providing links to edit or delete them.</li>
- <li><b>linkUser</b> - Generates a hyperlink to a details page
- for a User, which passes the required primary key values as
- request attributes.</li>
- </ul>
-
- <p>
- The source code for these tags is in the <code>src/example</code>
directory,
- in package <code>org.apache.struts.example</code>, along with the other
Java
- classes that are used in this application.
- </p>
- </section>
-
- <section name="3.4.2 Page Composition With Includes" href="includes">
-
- <p>
- Creating the entire presentation of a page in one JSP file (with custom
- tags and beans to access the required dynamic data) is a very common
design
- approach, and was employed in the example application included with
Struts.
- However, many applications require the display of multiple logically
distinct
- portions of your application together on a single page.</p>
-
- <p>
- For example, a portal application might have some or all of the following
- functional capabilities available on the portal's "home" page:
- </p>
-
- <ul>
- <li>Access to a search engine for this portal.</li>
- <li>One or more "news feed" displays, with the topics of interest
customized
- from the user's registration profile.</li>
- <li>Access to discussion topics related to this portal.</li>
- <li>A "mail waiting" indicator if your portal provides free email
- accounts.</li>
- </ul>
-
- <p>
- The development of the various segments of this site is easier if you
- can divide up the work, and assign different developers to the different
- segments. Then, you can use the <i>include</i> capability of JavaServer
Pages
- technology to combine the results into a single result page, or use the
include tag
- provided with Struts. There are three
- types of <i>include</i> available, depending on when you want the
combination
- of output to occur:
- </p>
-
- <ul>
- <li>An <code><%@ include file="xxxxx" %></code> directive can
include a file that contains
- java code or jsp tags. The code in the included file can even reference
- variables declared earlier in the outer jsp page. The code is inlined
into
- the other jsp before it is compiled so it can definately contain more
than
- just HTML.</li>
- <li>The include <i>action</i> (<code><jsp:include page="xxxxx"
- flush="true" /></code>) is processed at request time, and is
handled
- transparently by the server. Among other things, that means you
- can conditionally perform the include by nesting it within a tag
- like <a href="../struts-logic.html#equals">equals</a> by using it's
- parameter attribute.</li>
- <li>The <a href="../struts-bean.html#include">bean:include</a> tag takes
either a
- an argument "forward" representing a logical name mapped to the jsp to
include,
- or the "id" argument, which represents a page context String variable
to print
- out to the jsp page.</li>
- </ul>
- <p>
- Another approach to this would be to use the Struts Template Tag library.
See the
- Developer's Guide for details.
- </p>
- </section>
-
- <section name="3.4.3 Image Rendering Components" href="image_rendering">
-
- <p>
- Some applications require dynamically generated images, like the price
- charts on a stock reporting site. Two different approaches are commonly
used
- to meet these requirements:
- </p>
-
- <ul>
- <li>Render a hyperlink with a URL that executes a servlet request. The
- servlet will use a graphics library to render the graphical image,
- set the content type appropriately (such as to
<code>image/gif</code>),
- and send back the bytes of that image to the browser, which will
display
- them just as if it had received a static file.</li>
- <li>Render the HTML code necessary to download a Java applet that creates
- the required graph. You can configure the graph by setting
appropriate
- initialization parameters for the applet in the rendered code, or you
- can have the applet make its own connection to the server to receive
- these parameters.</li>
- </ul>
-
- <p align="center">
- Next: <a href="building_controller.html">Building Controller
Components</a>
- </p>
- </section>
- </section>
- </chapter>
- </body>
-</document>
-
-
-
-
+<?xml version="1.0"?>
+<document url="./building_view.xml">
+
+ <properties>
+ <author>Craig R. McClanahan</author>
+ <author>Mike Schachter</author>
+ <author>Ted Husted</author>
+ <title>The Struts User's Guide - Building View Components</title>
+ </properties>
+
+ <body>
+ <chapter name="3. Building View Components" href="building_view">
+
+ <section name="3.1 Overview" href="overview">
+
+ <p>
+ This chapter focuses on the task of building the <i>View</i> components
+ of the application, which will primarily be created using JavaServer Pages
+ (JSP) technology. In particular, Struts provides support for building
+ internationalized applications, as well as for interacting with input forms.
+ Several other topics related to the View components are briefly discussed.
+ </p>
+
+ </section>
+
+ <section name="3.2 Internationalized Messages" href="i18n">
+
+ <p>
+ A few years ago, application developers could count on having to support
+ only residents of their own country, who are used to only one (or sometimes
+ two) languages, and one way to represent numeric quantities like dates,
+ numbers, and monetary values. However, the explosion of application
+ development based on web technologies, as well as the deployment of such
+ applications on the Internet and other broadly accessible networks, have
+ rendered national boundaries invisible in many cases. This has translated
+ (if you will pardon the pun) into a need for applications to support
+ <i>internationalization</i> (often called "i18n" because 18 is the number of
+ letters in between the "i" and the "n") and <i>localization</i>.
+ </p>
+
+ <p>
+ Struts builds upon the Java platform to provide assistance
+ for building internationalized and localized applications. The key concepts
+ to become familiar with are:
+ </p>
+
+ <ul>
+ <li><b>Locale</b> - The fundamental Java class that supports
+ internationalization is <code>java.util.Locale</code>. Each
+ <code>Locale</code> represents a particular choice of country and
+ language (plus an optional language variant), and also a set of
+ formatting assumptions for things like numbers and dates.</li>
+ <li><b>ResourceBundle</b> - The <code>java.util.ResourceBundle</code> class
+ provides the fundmental tools for supporting messages in multiple
+ languages. See the Javadocs for the <code>ResourceBundle</code> class,
+ and the information on Internationalization in the documentation bundle
+ for your JDK release, for more information.</li>
+ <li><b>PropertyResourceBundle</b> - One of the standard implementations of
+ <code>ResourceBundle</code> allows you to define resources using the
+ same "name=value" syntax used to initialize properties files. This is
+ very convenient for preparing resource bundles with messages that are
+ used in a web application, because these messages are generally text
+ oriented.</li>
+ <li><b>MessageFormat</b> - The <code>java.text.MessageFormat</code> class
+ allows you to replace portions of a message string (in this case,
+ one retrieved from a resource bundle) with arguments specified at
+ run time. This is useful in cases where you are creating a sentence,
+ but the words would appear in a different order in different languages.
+ The placeholder string <code>{0}</code> in the message is replaced by
+ the first runtime argument, <code>{1}</code> is replaced by the second
+ argument, and so on.</li>
+ <li><b>MessageResources</b> - The Struts class
+ <code><a
href="api/org/apache/struts/util/MessageResources.html">org.apache.struts.util.MessageResources</a></code>
lets you treat
+ a set of resource bundles like a database, and allows you to request
+ a particular message string for a particular Locale (normally one
+ associated with the current user) instead of for the default Locale
+ the server itself is running in.</li>
+ </ul>
+
+ <p>
+ For an internationalized application, follow the steps described in
+ the Internationalization document in the JDK documentation bundle for your
+ platform to create a properties file containing the messages for each
+ language. An example will illustrate this further:
+ </p>
+
+ <p>
+ Assume that your source code is created in package
+ <code>com.mycompany.mypackage</code>, so it is stored in a directory
+ (relative to your source directory) named
+ <code>com/mycompany/mypackage</code>. To create a resource bundle called
+ <code>com.mycompany.mypackage.MyResources</code>, you would create the
+ following files in the <code>com/mycompany/mypackage</code> directory:
+ </p>
+
+ <ul>
+ <li><b>MyResources.properties</b> - Contains the messages in the default
+ language for your server. If your default language is English, you
+ might have an entry like this:
+ <code>prompt.hello=Hello</code></li>
+ <li><b>MyResources_xx.properties</b> - Contains the same messages in the
+ language whose ISO language code is "xx" (See the ResourceBundle
+ Javadoc page for a link to the current list). For a French version
+ of the message shown above, you would have this entry:
+ <code>prompt.hello=Bonjour</code>
+ You can have resource bundle files for as many languages as you
need.</li>
+ </ul>
+
+ <p>
+ When you configue the controller servlet in the web application
+ deployment descriptor, one of the things you will need to define in
+ an initialization parameter is the base name of the resource bundle
+ for the application. In the case described above, it would be
+ <code>com.mycompany.mypackage.MyResources</code>.
+ </p>
+<pre>
+<servlet>
+ <servlet-name>action</servlet-name>
+ <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.mycompany.mypackage.MyResources</param-value>
+ </init-param>
+ <.../>
+</servlet>
+</pre>
+
+ <p>
+ The important thing is for the resource bundle to be found on the
+ class path for your application. Another approach is to store
+ the <code>MyResources.properties</code> file in your application's
+ class folder. You can then simply specify "myResources" as the
+ application value.
+ </p>
+ </section>
+
+ <section name="3.3 Forms and FormBean Interactions" href="form_beans">
+
+ <p>
+ At one time or another, most web developers have built forms using
+ the standard capabilities of HTML, such as the <code><input></code>
+ tag. Users have come to expect interactive applications to have certain
+ behaviors, and one of these expectations relates to error handling -- if
+ the user makes an error, the application should allow them to fix just what
+ needs to be changed -- without having to re-enter any of the rest of the
+ information on the current page or form.
+ </p>
+
+ <p>
+ Fulfilling this expectation is tedious and cumbersome when coding with
+ standard HTML and JSP pages. For example, an input element for a
+ <code>username</code> field might look like this (in JSP):
+ </p>
+
+<pre>
+<input type="text" name="username"
+ value="<%= loginBean.getUsername() %>"/>
+</pre>
+
+ <p>
+ which is difficult to type correctly, confuses HTML developers who are
+ not knowledgeable about programming concepts, and can cause problems with
+ HTML editors. Instead, Struts provides a comprehensive facility for
+ building forms, based on the Custom Tag Library facility of JSP 1.1.
+ The case above would be rendered like this using Struts:
+ </p>
+
+<pre>
+<html:text property="username"/>
+</pre>
+
+ <p>
+ with no need to explicitly refer to the JavaBean from which the initial
+ value is retrieved. That is handled automatically by the framework.
+ </p>
+ <p>
+ HTML forms are sometimes used to upload other files. Most browsers
+ support this through a <input type="file"> element, that generates
+ a file browse button, but it's up to the developer to handle the incoming
+ files. Struts handles these "multipart" forms in a way identical to
+ building normal forms. In the next section, we will cover using Struts to
+ create a simple login form, and also a simple mulitpart form.
+ </p>
+
+ <section name="3.3.1 Building Forms With Struts" href="forms">
+
+ <p>
+ A complete example of a login form will illustrate how Struts
+ makes dealing with forms much less painful than using straight HTML
+ and standard JSP facilities. Consider the following page (based on the
+ example application included with Struts) named <code>logon.jsp</code>:
+ </p>
+<hr/>
+<pre>
+<%@ page language="java" %>
+<%@ taglib uri="/WEB-INF/struts-html.tld"
+ prefix="html" %>
+<%@ taglib uri="/WEB-INF/struts-bean.tld"
+ prefix="bean" %>
+<html:html>
+<head>
+<title>
+ <bean:message key="logon.title"/>
+</title>
+<body bgcolor="white">
+<html:errors/>
+<html:form name="logonForm" action="logon.do"
+ type="org.apache.struts.example.LogonForm">
+<table border="0" width="100%">
+ <tr>
+ <th align="right">
+ <html:message key="prompt.username"/>
+ </th>
+ <td align="left">
+ <html:text property="username"
+ size="16"/>
+ </td>
+ </tr>
+ <tr>
+ <th align="right">
+ <html:message key="prompt.password"/>
+ </th>
+ <td align="left">
+ <html:password property="password"
+ size="16"/>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ <struts:submit>
+ <bean:message key="button.submit"/>
+ </struts:submit>
+ </td>
+ <td align="right">
+ <html:reset>
+ <bean:message key="button.reset"/>
+ </html:reset>
+ </td>
+ </tr>
+</table>
+</html:form>
+</body>
+</html:html>
+</pre>
+<hr/>
+ <p>
+ The following items illustrate the key features of form handling in
Struts,
+ based on this example:
+ </p>
+
+ <ul>
+ <li>The <code>taglib</code> directive tells the JSP page compiler where to
+ find the <i>tag library descriptor</i> for the Struts tag library. In
+ this case, we are using <code>bean</code> as the prefix that
identifies
+ tags from the struts-bean library, and "html" as the prefix that
identifies
+ tags from the struts-html library. Any desired prefix can be
used.</li>
+ <li>This page uses several occurrences of the
+ message tag to look up internationalized
+ message strings from a <code>MessageResources</code> object containing
+ all the resources for this application. For this page to work, the
+ following message keys must be defined in these resources:
+ <ul>
+ <li><b>logon.title</b> - Title of the logon page</li>
+ <li><b>prompt.username</b> - A "Username:" prompt string</li>
+ <li><b>prompt.password</b> - A "Password:" prompt string</li>
+ <li><b>button.submit</b> - "Submit" for the button label</li>
+ <li><b>button.reset</b> - "Reset" for the button label</li>
+ </ul>
+ When the user logs on, the application can store a <code>Locale</code>
+ object in the user's session. This <code>Locale</code> will be used
+ to select messages in the appropriate language. This makes it easy to
+ implement giving the user an option to switch languages -- simply
change
+ the stored <code>Locale</code> object, and all messages are switched
+ automatically.</li>
+ <li>The errors tag displays any error
+ messages that have been stored by a business logic component, or
nothing
+ if no errors have been stored. This tag will be described further
+ below.</li>
+ <li>The form tag renders an HTML
+ <code><form></code> element, based on the specified attributes.
+ It also associates all of the fields within this form with a session
+ scoped FormBean that is stored under the key <code>logonForm</code>.
+ This bean is used to provide initial values for all of the input
+ fields that have names matching the property names of the bean.
+ If an appropriate bean is not found, a new one will be created
+ automatically, using the specified Java class name.
+ <li>The form bean can also be specified in the Struts configuration
file,
+ in which case the Name and Type can be omitted
+ here. See "<a href="building_controller.html#config">The Action
Mappings
+ Configuration File</a>" for details.)</li>
+ </li>
+ <li>The text tag renders an HTML
+ <code><input></code> element of type "text". In this case,
+ the number of character positions to occupy on the browser's screen
+ has been specified as well. When this page is executed, the current
+ value of the <code>username</code> property of the corresponding bean
+ (that is, the value returned by <code>getUsername()</code>).</li>
+ <li>The password tag is used similarly.
+ The difference is that the browser will echo asterisk characters,
+ instead of the input value, as the user types their password.</li>.
+ <li>The submit and
+ reset tags generate the corresponding
+ buttons at the bottom of the form. The text labels for each button
+ are created using message tags,
+ as with the prompts, so that these values are internationalized.</li>
+ </ul>
+
+ <p>
+ Handling multipart forms is also easy. Obviously when you create a
multipart
+ form you're creating a form that has at least one input of type "file".
The first step to
+ creating a multipart form is to utilize the struts-html taglib to create
the presentation
+ page:
+ </p>
+
+<hr/>
+<pre>
+<%@page language="java">
+<%@taglib uri="/WEB-INF/struts-html.tld"
+ prefix="html">
+<html:form action="uploadAction.do">
+ Please Input Text:
+ <html:text property="myText"><br/>
+ Please Input The File You Wish to Upload:<br/>
+ <html:file property="myFile"><br />
+ <html:submit />
+</html:form>
+</pre>
+<hr/>
+ <p>
+ The next step is to create your ActionForm bean:
+ </p>
+
+<hr/>
+<pre>
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.upload.FormFile;
+public class UploadForm extends ActionForm {
+ protected String myText;
+ protected FormFile myFile;
+ public void setMyText(String text) {
+ myText = text;
+ }
+ public String getMyText() {
+ return myText;
+ }
+ public void setMyFile(FormFile file) {
+ myFile = file;
+ }
+ public FormFile getMyFile() {
+ return myFile;
+ }
+}
+</pre>
+<hr/>
+ <p>
+ Look at the <a href="../api/index.html">javadocs</a> for FormFile to see
the
+ methods it exposes to manipulate files in file uploading. Also look at
the
+ javadocs for ActionServlet and ActionMapping for the various parameters
+ you can specify to change how files are uploaded. Basically in your
+ peform() method in your action class you would call <code>((UploadForm)
form).getMyFile()</code>
+ to retrieve the FormFile and do what you want with it.
+ </p>
+
+ </section>
+
+ <section name="3.3.2 Input Field Types Supported" href="form_input">
+
+ <p>
+ Struts defines HTML tags for all of the following types of input fields,
+ with hyperlinks to the corresponding reference information.
+ </p>
+
+ <ul>
+ <li><a href="../struts-html.html#checkbox">checkboxes</a></li>
+ <li><a href="../struts-html.html#hidden">hidden</a> fields</li>
+ <li><a href="../struts-html.html#password">password</a> input
fields</li>
+ <li><a href="../struts-html.html#radio">radio</a> buttons</li>
+ <li><a href="../struts-html.html#reset">reset</a> buttons</li>
+ <li><a href="../struts-html.html#select">select</a> lists with
embedded</li>
+ <li><a href="../struts-html.html#option">options</a></li>
+ <li><a href="../struts-html.html#submit">submit</a> buttons</li>
+ <li><a href="../struts-html.html#text">text</a> input fields</li>
+ <li><a href="../struts-html.html#textarea">textareas</a></li>
+ </ul>
+
+ <p>
+ In every
+ case, a field tag must be nested within a <code>form</code> tag, so that
+ the field knows what bean to use for initializing displayed values.
+ </p>
+ </section>
+
+ <section name="3.3.3 Other Useful Presentation Tags" href="presentation_tags">
+
+ <p>
+ There are several tags useful for creating presentations, consult the
documentation
+ on each specific tag library, along with the Tag Developers Guides, for
more
+ information:
+ </p>
+
+ <ul>
+
+ <li>[logic] <a href="../struts-logic.html#iterate">iterate</a> repeats
its tag body once
+ for each element of a specified collection (which can be an
Enumeration,
+ a Hashtable, a Vector, or an array of objects).</li>
+ <li>[logic] <a href="../struts-logic.html#present">present</a> depending
on which attribute
+ is specified, this tag checks the current request, and evaluates the
nested
+ body content of this tag only if the specified value is present. Only
one of
+ the attributes may be used in one occurrence of this tag, unless you
use the
+ property attribute, in which case the name attribute is also
required. The
+ attributes include cookie, header, name, parameter, property, role,
scope,
+ and user.
+ </li>
+ <li>[logic] <a href="../struts-logic.html#notPresent">notPresent</a> the
companion tag to
+ present, notPresent provides the same functionality when the
specified attribute
+ is not present.</li>
+ <li>[html] <a href="../struts-html.html#link">link</a> generates a HTML
<a> element
+ as an anchor definition or a hyperlink to the specified URL, and
automatically
+ applies URL encoding to maintain session state in the absence of
+ cookie support.</li>
+ <li>[html] <a href="../struts-html.html#img">img</a> generates a HTML
<img> element
+ with the ability to dynamically modify the URLs specified by the
"src" and
+ "lowsrc" attributes in the same manner that <html:link> can.
+ </li>
+ <li>[bean] <a href="../struts-bean.html#parameter">parameter</a>
retrieves the value of the
+ specified request parameter, and defines the result as a page scope
attribute of
+ type String or String[].</li>
+ </ul>
+
+ </section>
+
+ <section name="3.3.4 Automatic Form Validation" href="form_validation">
+
+ <p>
+ In addition to the form and bean interactions described above, Struts
+ offers an additional facility to validate the input fields it has
received.
+ To utilize this feature, override the following method in your ActionForm
+ class:
+ </p>
+
+<pre>public ActionErrors
+ validate(ActionMapping mapping,
+ HttpServletRequest request);
+</pre>
+
+ <p>
+ The validate() method is called by the controller servlet after the bean
+ properties have been populated, but before the corresponding action
class's
+ <code>perform()</code> method is invoked. The <code>validate()</code>
method
+ has the following options:
+ </p>
+
+ <ul>
+ <li>Perform the appropriate validations and find no problems -- Return
either
+ <code>null</code> or a zero-length ActionErrors instance, and the
controller
+ servlet will proceed to call the <code>perform()</code> method of the
+ appropriate <code>Action</code> class.</li>
+ <li>Perform the appropriate validations and find problems -- Return an
ActionErrors
+ instance containing <code>ActionError</code>'s, which are classes
that contain
+ the error message keys (into the application's
+ <code>MessageResources</code> bundle) that should be displayed. The
+ controller servlet will store this array as a request attribute
suitable
+ for use by the <code><html:errors></code> tag, and will forward
+ control back to the input form (identified by the
<code>inputForm</code>
+ property for this <code>ActionMapping</code>).</li>
+ </ul>
+
+ <p>
+ As mentioned earlier, this feature is entirely optional. The default
implementation
+ of the validate() method returns <code>null</code>, and the controller
servlet
+ will assume that any required validation is done by the action class.
+ </p>
+ <p>
+ One common approach is to perform simple validations using the validate()
method, and
+ also provide further "business logic" validation as part of your Action
object.
+ </p>
+
+ </section>
+ </section>
+
+ <section name="3.4 Other Presentation Techniques" href="other_presentations">
+
+ <p>
+ Although the look and feel of your application can be completely constructed
+ based on the standard capabilities of JSP and the Struts custom tag library,
+ you should consider employing other techniques that will improve component
+ reuse, reduce maintenance efforts, and/or reduce errors. Several options
+ are discussed in the following sections.
+ </p>
+
+ <section name="3.4.1 Application-Specific Custom Tags" href="custom_tags">
+
+ <p>
+ Beyond using the custom tags provided by the Struts library, it is easy
+ to create tags that are specific to the application you are building, to
+ assist in creating the user interface. The example application included
with
+ Struts illustrates this principle by creating the following tags unique to
+ the implementation of this application:
+ </p>
+
+ <ul>
+ <li><b>checkLogon</b> - Checks for the existence of a particular session
+ object, and forwards control to the logon page if it is missing.
This is
+ used to catch cases where a user has bookmarked a page in the middle
of
+ your application and tries to bypass logging on, or if the user's
session
+ has been timed out.</li>
+ <li><b>linkSubscription</b> - Generates a hyperlink to a details page
+ for a Subscription, which passes the required primary key values as
+ request attributes. This is used when listing the subscriptions
associated
+ with a user, and providing links to edit or delete them.</li>
+ <li><b>linkUser</b> - Generates a hyperlink to a details page
+ for a User, which passes the required primary key values as
+ request attributes.</li>
+ </ul>
+
+ <p>
+ The source code for these tags is in the <code>src/example</code>
directory,
+ in package <code>org.apache.struts.example</code>, along with the other
Java
+ classes that are used in this application.
+ </p>
+ </section>
+
+ <section name="3.4.2 Page Composition With Includes" href="includes">
+
+ <p>
+ Creating the entire presentation of a page in one JSP file (with custom
+ tags and beans to access the required dynamic data) is a very common
design
+ approach, and was employed in the example application included with
Struts.
+ However, many applications require the display of multiple logically
distinct
+ portions of your application together on a single page.</p>
+
+ <p>
+ For example, a portal application might have some or all of the following
+ functional capabilities available on the portal's "home" page:
+ </p>
+
+ <ul>
+ <li>Access to a search engine for this portal.</li>
+ <li>One or more "news feed" displays, with the topics of interest
customized
+ from the user's registration profile.</li>
+ <li>Access to discussion topics related to this portal.</li>
+ <li>A "mail waiting" indicator if your portal provides free email
+ accounts.</li>
+ </ul>
+
+ <p>
+ The development of the various segments of this site is easier if you
+ can divide up the work, and assign different developers to the different
+ segments. Then, you can use the <i>include</i> capability of JavaServer
Pages
+ technology to combine the results into a single result page, or use the
include tag
+ provided with Struts. There are three
+ types of <i>include</i> available, depending on when you want the
combination
+ of output to occur:
+ </p>
+
+ <ul>
+ <li>An <code><%@ include file="xxxxx" %></code> directive can
include a file that contains
+ java code or jsp tags. The code in the included file can even reference
+ variables declared earlier in the outer jsp page. The code is inlined into
+ the other jsp before it is compiled so it can definately contain more than
+ just HTML.</li>
+ <li>The include <i>action</i> (<code><jsp:include page="xxxxx"
+ flush="true" /></code>) is processed at request time, and is
handled
+ transparently by the server. Among other things, that means you
+ can conditionally perform the include by nesting it within a tag
+ like <a href="../struts-logic.html#equals">equals</a> by using it's
+ parameter attribute.</li>
+ <li>The <a href="../struts-bean.html#include">bean:include</a> tag takes
either a
+ an argument "forward" representing a logical name mapped to the jsp to
include,
+ or the "id" argument, which represents a page context String variable
to print
+ out to the jsp page.</li>
+ </ul>
+ <p>
+ Another approach to this would be to use the Struts Template Tag library.
See the
+ Developer's Guide for details.
+ </p>
+ </section>
+
+ <section name="3.4.3 Image Rendering Components" href="image_rendering">
+
+ <p>
+ Some applications require dynamically generated images, like the price
+ charts on a stock reporting site. Two different approaches are commonly
used
+ to meet these requirements:
+ </p>
+
+ <ul>
+ <li>Render a hyperlink with a URL that executes a servlet request. The
+ servlet will use a graphics library to render the graphical image,
+ set the content type appropriately (such as to
<code>image/gif</code>),
+ and send back the bytes of that image to the browser, which will
display
+ them just as if it had received a static file.</li>
+ <li>Render the HTML code necessary to download a Java applet that creates
+ the required graph. You can configure the graph by setting
appropriate
+ initialization parameters for the applet in the rendered code, or you
+ can have the applet make its own connection to the server to receive
+ these parameters.</li>
+ </ul>
+
+ <p align="center">
+ Next: <a href="building_controller.html">Building Controller
Components</a>
+ </p>
+ </section>
+ </section>
+ </chapter>
+ </body>
+</document>
+
+
+
+
1.13 +263 -240 jakarta-struts/src/doc/userGuide/building_model.xml
Index: building_model.xml
===================================================================
RCS file: /home/cvs/jakarta-struts/src/doc/userGuide/building_model.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- building_model.xml 2001/02/11 21:39:20 1.12
+++ building_model.xml 2001/02/11 22:56:59 1.13
@@ -1,240 +1,263 @@
-<?xml version="1.0"?>
-<document url="./building_model.xml">
-
- <properties>
- <author>Craig R. McClanahan</author>
- <author>Mike Schachter</author>
- <author>Ted Husted</author>
- <title>The Struts User's Guide - Building Model Components</title>
- </properties>
-
- <body>
- <chapter name="2. Building Model Components" href="building_model">
-
- <section name="2.1 Overview" href="overview">
-
- <p>
- The application requirements document that you are using will likely
- have focused on the user interface to be created. However, you should
ensure
- that the processing required for each submitted request is also clearly
- defined. In general, the developer of the <i>Model</i> components will be
- focusing on the creation of JavaBeans classes that support all of the
- functional requirements. The precise nature of the beans required by a
- particular application will vary widely depending on those requirements,
- but they can generally be classified into several categories discussed
- below. However, a brief review of the concept of "scope" as it relates
- to beans is useful first.
- </p>
- </section>
-
- <section name="2.2 JavaBeans and Scope" href="javabeans">
-
- <p>
- Within a web-based application, JavaBeans can be stored in (and accessed
- from) a number of different collections of "attributes". Each collection
- has different rules for the lifetime of that collection, and the visibility
- of the beans stored there. Together, the rules defining lifetime and
- visibility are called the <i>scope</i> of those beans. The JavaServer
- Pages (JSP) Specification defines scope choices using the following terms
- (with the equivalent servlet API concept defined in parentheses):
- </p>
-
- <ul>
- <li><b>page</b> - Beans that are visible within a single JSP page,
- for the lifetime of the current request. (Local variables of
- the <code>service()</code> method)</li>
- <li><b>request</b> - Beans that are visible within a single JSP page,
- as well as to any page or servlet that is included in this page,
- or forwarded to by this page. (Request attributes)</li>
- <li><b>session</b> - Beans that are visible to all JSP pages and
- servlets that participate in a particular user session, across one
- or more requests. (Session attributes)</li>
- <li><b>application</b> - Beans that are visible to all JSP pages and
- servlets that are part of a web application. (Servlet context
- attributes)</li>
- </ul>
-
- <p>
- It is important to remember that JSP pages and servlets in the same
- web application share the same sets of bean collections. For example,
- a bean stored as a request attribute in a servlet like this:
- </p>
-
- <p><code>MyCart mycart = new MyCart(...);<br />
- request.setAttribute("cart", mycart);
- </code></p>
-
- <p>
- is immediately visible to a JSP page which this servlet forwards to,
- using a standard action tag like this:
- </p>
-
- <p><code><jsp:useBean id="cart" scope="request"<br />
- class="com.mycompany.MyApp.MyCart"/>
- </code></p>
- </section>
-
- <section name="2.3 ActionForm Beans" href="actionform">
-
- <p>
- Note: ActionForm beans are actually closer to the <i>View</i>
- than the <i>Model</i>.
- </p>
- <p>
- The Struts framework generally assumes that you have created an
- <code>ActionForm</code> bean (that is, a Java class extending the
- <code>ActionForm</code> class) for each input form required in your
- application. If you define such beans in your <code>ActionMapping</code>
- configuration file (see "<a href="building_controller.html#config">
- Building the Controller Components</a>"), the Struts controller servlet
- will automatically perform the following services for you, before
- invoking the appropriate <code>Action</code> method:
- </p>
-
- <ul>
- <li>Check in the user's session for an instance of a bean of the
- appropriate class, under the appropriate key.</li>
- <li>If there is no such session scope bean available, a new one is
- automatically created and added to the user's session.</li>
- <li>For every request parameter whose name corresponds to the name
- of a property in the bean, the corresponding setter method will
- be called. This operates in a manner similar to the standard
- JSP action <code><jsp:setProperty></code> when you use the
- asterisk wildcard to select all properties.</li>
- <li>The updated <code>ActionForm</code> bean will be passed to the
- Action Class <code>perform()</code> method when it is called,
- making these values immediately available.</li>
- </ul>
-
- <p>
- When you code your <code>ActionForm</code> beans, keep the following
- principles in mind:
- </p>
-
- <ul>
- <li>The <code>ActionForm</code> class itself requires no specific
- methods to be implemented. It is used to identify the role these
- particular beans play in the overall architecture. Typically, an
- <code>ActionForm</code> bean will have only property getter and
- property setter methods, with no business logic.</li>
- <li>The ActionForm object also offers a standard validation mechanism.
- If you override a "stub" method, and provide error messages in the
- standard application resource, Struts will automatically validate the
- input from the form (using your method). See "<a
- href="./building_view.html#form_validation">Action Form Validation</a>"
- for details. Of course, you can also ignore the ActionForm validation
- and provide your own in the Action object.</li>
- <li>Define a property (with associated <code>getXxx()</code> and
- <code>setXxx()</code> methods) for each field that is present
- in the form. The field name and property name must match according
- to the usual JavaBeans conventions. For example, an input field named
- <code>username</code> will cause the <code>setUsername()</code> method
- to be called.</li>
- <li>You may also place a bean instance on your form, and use nested
property
- references. For example, you might have a "customer" bean on your
Action
- Form, and then refer to the property "customer.name" in your JSP view.
- This would correspond to the methods <code>customer.getName()</code>
and
- <code>customer.setName(string Name)</code> on your customer bean. See
the
- Tag Library Developer Guides for more about nested syntax.</li>
- </ul>
-
- <p>
- You should note that a "form", in the sense discussed here, does not
- necessarily correspond to a single JSP page in the user interface. It is
- common in many applications to have a "form" (from the user's perspective)
- that extends over multiple pages. Think, for example, of the wizard style
- user interface that is commonly used when installing new applications.
Struts
- encourages you to define a single <code>ActionForm</code> bean that
contains
- properties for all of the fields, no matter which page the field is
actually
- displayed on. Likewise, the various pages of the same form should all be
- submitted to the same Action Class. If you follow these suggestions, the
- page designers can rearrange the fields among the various pages, pftem
without
- requiring changes to the processing logic.
- </p>
- </section>
-
- <section name="2.4 System State Beans" href="system_state">
-
- <p>
- The actual state of a system is normally represented as a set of one or
- more JavaBeans classes, whose properties define the current state. A
- shopping cart system, for example, will include a bean that represents the
- cart being maintained for each individual shopper, and will (among other
- things) include the set of items that the shopper has currently selected
- for purchase. Separately, the system will also include different beans
- for the user's profile information (including their credit card and ship-to
- addresses), as well as the catalog of available items and their current
- inventory levels.
- </p>
-
- <p>
- For small scale systems, or for state information that need not be kept
- for a long period of time, a set of system state beans may contain all the
- knowledge that the system ever has of these particular details. Or, as is
- often the case, the system state beans will represent information that is
- stored permanently in some external database (such as a
<code>CustomerBean</code> object
- that corresponds to a particular row in the CUSTOMERS table), and are
- created or removed from the server's memory as needed. Entity Enterprise
- JavaBeans are also used for this purpose in large scale applications.
- </p>
- </section>
-
- <section name="2.5 Business Logic Beans" href="business_logic">
-
- <p>
- You should encapsulate the functional logic of your application as
- method calls on JavaBeans designed for this purpose. These methods may
- be part of the same classes used for the system state beans, or they may
- be in separate classes dedicated to performing the logic. In the latter
- case, you will usually need to pass the system state beans to be
manipulated
- to these methods as arguments.
- </p>
-
- <p>
- For maximum code re-use, business logic beans should be designed and
- implemented so that they do <b>not</b> know they are being executed in a
- web application environment. If you find yourself having to import a
- <code>javax.servlet.*</code> class in your bean, you
- are tying this business logic to the web application environment. Consider
- rearranging things so that your <code>Action</code> classes (part of the
- Controller role, as described below) translate all required information
- from the HTTP request being processed into property setter calls on your
- business logic beans, after which a call to an <code>execute()</code>
method
- can be made. Such a business logic class can be reused in environments
- other than the web application for which they were initially constructed.
- </p>
-
- <p>
- Depending on the complexity and scope of your application, business logic
- beans might be ordinary JavaBeans that interact with system state beans
- passed as arguments, or ordinary JavaBeans that access a database using
- JDBC calls. For larger applications, these beans will often be stateful
- or stateless Enterprise JavaBeans (EJBs) instead.
- </p>
- </section>
-
- <section name="2.6 Accessing Relational Databases" href="databases">
-
- <p>
- Struts can define the datasources for an application from within its
standard
- configuration file. A simple JDBC connection pool is also provided. See <a
- href="building_controller.html#config">The Action Mappings Configuration
File</a>
- section and the Utilities Developer Guide for details.
- </p>
- <p>
- After the datasource is defined, here is an example of establishing a
connection
- from within a Action perform method.
- </p>
-<pre>
-public ActionForward<br/> perform(ActionMapping mapping,<br/>
ActionForm form,<br/> HttpServletRequest request,<br/>
HttpServletResponse response)<br/>{<br/>
- try {<br/> javax.sql.DataSource dataSource =<br/>
servlet.findDataSource(null);<br/> java.sql.Connection myConnection =<br/>
dataSource.getConnection();<br/>
- //do what you wish with myConnection<br/> } catch (SQLException sqle) {<br/>
getServlet().log("Connection.process", sqle);<br/> } finally {<br/>
- //enclose this in a finally block to make<br/> //sure the connection is
closed<br/> try {<br/> myConnection.close();<br/> } catch (SQLException e)
{<br/> getServlet().log("Connection.close", e);<br/> }<br/>
}<br/>}<br/></pre>
-
- <p align="center">
- Next: <a href="building_view.html">Building View Components</a>
- </p>
- </section>
- </chapter>
- </body>
-</document>
\ No newline at end of file
+<?xml version="1.0"?>
+<document url="./building_model.xml">
+
+ <properties>
+ <author>Craig R. McClanahan</author>
+ <author>Mike Schachter</author>
+ <author>Ted Husted</author>
+ <title>The Struts User's Guide - Building Model Components</title>
+ </properties>
+
+ <body>
+ <chapter name="2. Building Model Components" href="building_model">
+
+ <section name="2.1 Overview" href="overview">
+
+ <p>
+ The application requirements document that you are using will likely
+ have focused on the user interface to be created. However, you should
ensure
+ that the processing required for each submitted request is also clearly
+ defined. In general, the developer of the <i>Model</i> components will be
+ focusing on the creation of JavaBeans classes that support all of the
+ functional requirements. The precise nature of the beans required by a
+ particular application will vary widely depending on those requirements,
+ but they can generally be classified into several categories discussed
+ below. However, a brief review of the concept of "scope" as it relates
+ to beans is useful first.
+ </p>
+ </section>
+
+ <section name="2.2 JavaBeans and Scope" href="javabeans">
+
+ <p>
+ Within a web-based application, JavaBeans can be stored in (and accessed
+ from) a number of different collections of "attributes". Each collection
+ has different rules for the lifetime of that collection, and the visibility
+ of the beans stored there. Together, the rules defining lifetime and
+ visibility are called the <i>scope</i> of those beans. The JavaServer
+ Pages (JSP) Specification defines scope choices using the following terms
+ (with the equivalent servlet API concept defined in parentheses):
+ </p>
+
+ <ul>
+ <li><b>page</b> - Beans that are visible within a single JSP page,
+ for the lifetime of the current request. (Local variables of
+ the <code>service()</code> method)</li>
+ <li><b>request</b> - Beans that are visible within a single JSP page,
+ as well as to any page or servlet that is included in this page,
+ or forwarded to by this page. (Request attributes)</li>
+ <li><b>session</b> - Beans that are visible to all JSP pages and
+ servlets that participate in a particular user session, across one
+ or more requests. (Session attributes)</li>
+ <li><b>application</b> - Beans that are visible to all JSP pages and
+ servlets that are part of a web application. (Servlet context
+ attributes)</li>
+ </ul>
+
+ <p>
+ It is important to remember that JSP pages and servlets in the same
+ web application share the same sets of bean collections. For example,
+ a bean stored as a request attribute in a servlet like this:
+ </p>
+
+ <p><code>MyCart mycart = new MyCart(...);<br />
+ request.setAttribute("cart", mycart);
+ </code></p>
+
+ <p>
+ is immediately visible to a JSP page which this servlet forwards to,
+ using a standard action tag like this:
+ </p>
+
+ <p><code><jsp:useBean id="cart" scope="request"<br />
+ class="com.mycompany.MyApp.MyCart"/>
+ </code></p>
+ </section>
+
+ <section name="2.3 ActionForm Beans" href="actionform">
+
+ <p>
+ Note: ActionForm beans are actually closer to the <i>View</i>
+ than the <i>Model</i>.
+ </p>
+ <p>
+ The Struts framework generally assumes that you have created an
+ <code>ActionForm</code> bean (that is, a Java class extending the
+ <code>ActionForm</code> class) for each input form required in your
+ application. If you define such beans in your <code>ActionMapping</code>
+ configuration file (see "<a href="building_controller.html#config">
+ Building the Controller Components</a>"), the Struts controller servlet
+ will automatically perform the following services for you, before
+ invoking the appropriate <code>Action</code> method:
+ </p>
+
+ <ul>
+ <li>Check in the user's session for an instance of a bean of the
+ appropriate class, under the appropriate key.</li>
+ <li>If there is no such session scope bean available, a new one is
+ automatically created and added to the user's session.</li>
+ <li>For every request parameter whose name corresponds to the name
+ of a property in the bean, the corresponding setter method will
+ be called. This operates in a manner similar to the standard
+ JSP action <code><jsp:setProperty></code> when you use the
+ asterisk wildcard to select all properties.</li>
+ <li>The updated <code>ActionForm</code> bean will be passed to the
+ Action Class <code>perform()</code> method when it is called,
+ making these values immediately available.</li>
+ </ul>
+
+ <p>
+ When you code your <code>ActionForm</code> beans, keep the following
+ principles in mind:
+ </p>
+
+ <ul>
+ <li>The <code>ActionForm</code> class itself requires no specific
+ methods to be implemented. It is used to identify the role these
+ particular beans play in the overall architecture. Typically, an
+ <code>ActionForm</code> bean will have only property getter and
+ property setter methods, with no business logic.</li>
+ <li>The ActionForm object also offers a standard validation mechanism.
+ If you override a "stub" method, and provide error messages in the
+ standard application resource, Struts will automatically validate the
+ input from the form (using your method). See "<a
+ href="./building_view.html#form_validation">Action Form Validation</a>"
+ for details. Of course, you can also ignore the ActionForm validation
+ and provide your own in the Action object.</li>
+ <li>Define a property (with associated <code>getXxx()</code> and
+ <code>setXxx()</code> methods) for each field that is present
+ in the form. The field name and property name must match according
+ to the usual JavaBeans conventions. For example, an input field named
+ <code>username</code> will cause the <code>setUsername()</code> method
+ to be called.</li>
+ <li>You may also place a bean instance on your form, and use nested
property
+ references. For example, you might have a "customer" bean on your
Action
+ Form, and then refer to the property "customer.name" in your JSP view.
+ This would correspond to the methods <code>customer.getName()</code>
and
+ <code>customer.setName(string Name)</code> on your customer bean. See
the
+ Tag Library Developer Guides for more about nested syntax.</li>
+ </ul>
+
+ <p>
+ You should note that a "form", in the sense discussed here, does not
+ necessarily correspond to a single JSP page in the user interface. It is
+ common in many applications to have a "form" (from the user's perspective)
+ that extends over multiple pages. Think, for example, of the wizard style
+ user interface that is commonly used when installing new applications.
Struts
+ encourages you to define a single <code>ActionForm</code> bean that contains
+ properties for all of the fields, no matter which page the field is actually
+ displayed on. Likewise, the various pages of the same form should all be
+ submitted to the same Action Class. If you follow these suggestions, the
+ page designers can rearrange the fields among the various pages, pftem
without
+ requiring changes to the processing logic.
+ </p>
+ </section>
+
+ <section name="2.4 System State Beans" href="system_state">
+
+ <p>
+ The actual state of a system is normally represented as a set of one or
+ more JavaBeans classes, whose properties define the current state. A
+ shopping cart system, for example, will include a bean that represents the
+ cart being maintained for each individual shopper, and will (among other
+ things) include the set of items that the shopper has currently selected
+ for purchase. Separately, the system will also include different beans
+ for the user's profile information (including their credit card and ship-to
+ addresses), as well as the catalog of available items and their current
+ inventory levels.
+ </p>
+
+ <p>
+ For small scale systems, or for state information that need not be kept
+ for a long period of time, a set of system state beans may contain all the
+ knowledge that the system ever has of these particular details. Or, as is
+ often the case, the system state beans will represent information that is
+ stored permanently in some external database (such as a
<code>CustomerBean</code> object
+ that corresponds to a particular row in the CUSTOMERS table), and are
+ created or removed from the server's memory as needed. Entity Enterprise
+ JavaBeans are also used for this purpose in large scale applications.
+ </p>
+ </section>
+
+ <section name="2.5 Business Logic Beans" href="business_logic">
+
+ <p>
+ You should encapsulate the functional logic of your application as
+ method calls on JavaBeans designed for this purpose. These methods may
+ be part of the same classes used for the system state beans, or they may
+ be in separate classes dedicated to performing the logic. In the latter
+ case, you will usually need to pass the system state beans to be manipulated
+ to these methods as arguments.
+ </p>
+
+ <p>
+ For maximum code re-use, business logic beans should be designed and
+ implemented so that they do <b>not</b> know they are being executed in a
+ web application environment. If you find yourself having to import a
+ <code>javax.servlet.*</code> class in your bean, you
+ are tying this business logic to the web application environment. Consider
+ rearranging things so that your <code>Action</code> classes (part of the
+ Controller role, as described below) translate all required information
+ from the HTTP request being processed into property setter calls on your
+ business logic beans, after which a call to an <code>execute()</code> method
+ can be made. Such a business logic class can be reused in environments
+ other than the web application for which they were initially constructed.
+ </p>
+
+ <p>
+ Depending on the complexity and scope of your application, business logic
+ beans might be ordinary JavaBeans that interact with system state beans
+ passed as arguments, or ordinary JavaBeans that access a database using
+ JDBC calls. For larger applications, these beans will often be stateful
+ or stateless Enterprise JavaBeans (EJBs) instead.
+ </p>
+ </section>
+
+ <section name="2.6 Accessing Relational Databases" href="databases">
+
+ <p>
+ Struts can define the datasources for an application from within its
standard
+ configuration file. A simple JDBC connection pool is also provided. See <a
+ href="building_controller.html#config">The Action Mappings Configuration
File</a>
+ section and the Utilities Developer Guide for details.
+ </p>
+ <p>
+ After the datasource is defined, here is an example of establishing a
connection
+ from within a Action perform method.
+ </p>
+<pre>
+public ActionForward
+ perform(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+{
+ try {
+ javax.sql.DataSource dataSource =
+ servlet.findDataSource(null);
+ java.sql.Connection myConnection =
+ dataSource.getConnection();
+
+ //do what you wish with myConnection
+ } catch (SQLException sqle) {
+ getServlet().log("Connection.process", sqle);
+ } finally {
+
+ //enclose this in a finally block to make
+ //sure the connection is closed
+ try {
+ myConnection.close();
+ } catch (SQLException e) {
+ getServlet().log("Connection.close", e);
+ }
+ }
+}
+</pre>
+
+ <p align="center">
+ Next: <a href="building_view.html">Building View Components</a>
+ </p>
+ </section>
+ </chapter>
+ </body>
+</document>