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>