You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by hu...@apache.org on 2006/01/21 01:21:00 UTC
svn commit: r370938 [25/50] - in /struts: action/trunk/
action/trunk/conf/java/ action/trunk/src/java/org/apache/struts/
action/trunk/src/java/org/apache/struts/action/
action/trunk/src/java/org/apache/struts/chain/
action/trunk/src/java/org/apache/str...
Modified: struts/action/trunk/src/test/org/apache/struts/validator/TestValidWhen.java
URL: http://svn.apache.org/viewcvs/struts/action/trunk/src/test/org/apache/struts/validator/TestValidWhen.java?rev=370938&r1=370937&r2=370938&view=diff
==============================================================================
--- struts/action/trunk/src/test/org/apache/struts/validator/TestValidWhen.java (original)
+++ struts/action/trunk/src/test/org/apache/struts/validator/TestValidWhen.java Fri Jan 20 16:19:02 2006
@@ -1,42 +1,41 @@
/*
- * $Id$
+ * $Id$
*
* Copyright 2004 The Apache Software Foundation.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.struts.validator;
-import java.io.StringReader;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.struts.validator.validwhen.ValidWhenLexer;
import org.apache.struts.validator.validwhen.ValidWhenParser;
-import org.apache.commons.validator.util.ValidatorUtils;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.logging.Log;
+import java.io.StringReader;
/**
* Unit tests for the ValidWhen Parser/Lexer.
*/
public class TestValidWhen extends TestCase {
-
- /** All logging goes through this logger */
+ /**
+ * All logging goes through this logger
+ */
private static Log log = LogFactory.getLog(TestValidWhen.class);
-
protected PojoBean testBean;
/**
@@ -54,8 +53,8 @@
* @param theArgs the arguments. Not used
*/
public static void main(String[] theArgs) {
- junit.awtui.TestRunner.main(
- new String[] {TestValidWhen.class.getName()});
+ junit.awtui.TestRunner
+ .main(new String[]{TestValidWhen.class.getName()});
}
/**
@@ -69,194 +68,221 @@
public void setUp() {
testBean = new PojoBean(123, 789);
- testBean.setStringValue1("ABC");
+ testBean.setStringValue1("ABC");
testBean.setStringValue2(null);
- testBean.setBeans(new PojoBean[] {new PojoBean(11, 12),
- new PojoBean(21, 22),
- new PojoBean(31, 42),
- new PojoBean(41, 52),
- new PojoBean(51, 62)});
+ testBean.setBeans(new PojoBean[]{
+ new PojoBean(11, 12), new PojoBean(21, 22),
+ new PojoBean(31, 42),
+ new PojoBean(41, 52), new PojoBean(51, 62)
+ });
testBean.setMapped("testKey", "mappedValue");
}
public void tearDown() {
testBean = null;
}
-
+
/**
* Test Operators.
*/
public void testProperty() {
-
// *this*
- doParse("(*this* == 123)", testBean , 0, "intValue1", true);
+ doParse("(*this* == 123)", testBean, 0, "intValue1", true);
// Named property
- doParse("(intValue2 == 789)", testBean , 0, "intValue1", true);
+ doParse("(intValue2 == 789)", testBean, 0, "intValue1", true);
// Indexed Property
- doParse("(beans[].intValue1 == 21)", testBean , 1, "intValue1", true);
- doParse("(beans[1].intValue1 == 21)", testBean , 4, "intValue1", true);
+ doParse("(beans[].intValue1 == 21)", testBean, 1, "intValue1", true);
+ doParse("(beans[1].intValue1 == 21)", testBean, 4, "intValue1", true);
// Mapped Property - *** NOT SUPPORTED ***
// doParse("(mapped(mappedValue) == 'testKey')", testBean , 0, "mappedValue", true);
-
-
}
-
+
/**
* Test Operators.
*/
public void testOperators() {
-
// Equal
- doParse("(*this* == 123)", testBean , 0, "intValue1", true);
+ doParse("(*this* == 123)", testBean, 0, "intValue1", true);
// Not Equal
- doParse("(*this* != 456)", testBean , 0, "intValue1", true);
+ doParse("(*this* != 456)", testBean, 0, "intValue1", true);
// Less Than
- doParse("(*this* < 456)", testBean , 0, "intValue1", true);
+ doParse("(*this* < 456)", testBean, 0, "intValue1", true);
// Greater Than
- doParse("(*this* > 100)", testBean , 0, "intValue1", true);
+ doParse("(*this* > 100)", testBean, 0, "intValue1", true);
// Less Than Equal
- doParse("(*this* <= 123)", testBean , 0, "intValue1", true);
+ doParse("(*this* <= 123)", testBean, 0, "intValue1", true);
// Greater Than Equal
- doParse("(*this* >= 123)", testBean , 0, "intValue1", true);
-
+ doParse("(*this* >= 123)", testBean, 0, "intValue1", true);
}
/**
* Test String values.
*/
public void testString() {
+ doParse("(*this* != '--')", "XX", 0, "stringValue1", true);
+ doParse("(*this* == '--')", "--", 0, "stringValue1", true);
- doParse("(*this* != '--')", "XX", 0, "stringValue1", true);
- doParse("(*this* == '--')", "--", 0, "stringValue1", true);
-
+ String testValue = "dsgUOLMdLsdL";
- String testValue = "dsgUOLMdLsdL";
-
- // single quote
- doParse("(*this* == '" + testValue + "')", testValue, 0, "stringValue1", true);
-
- // double quote
- doParse("(*this* == \"" + testValue + "\")", testValue, 0, "stringValue1", true);
+ // single quote
+ doParse("(*this* == '" + testValue + "')", testValue, 0,
+ "stringValue1", true);
+
+ // double quote
+ doParse("(*this* == \"" + testValue + "\")", testValue, 0,
+ "stringValue1", true);
}
-
+
/**
* Test Numeric values.
*/
public void testNumeric() {
-
// Test Zero
PojoBean numberBean = new PojoBean(0, -50);
+
doParse("(intValue1 == 0)", numberBean, 0, "intValue1", true);
doParse("(intValue2 != 0)", numberBean, 0, "intValue2", true);
doParse("(integerValue1 == 0)", numberBean, 0, "integerValue1", true);
doParse("(integerValue2 != 0)", numberBean, 0, "integerValue2", true);
// int
- doParse("(intValue1 == 123)", testBean , 0, "intValue1", true);
+ doParse("(intValue1 == 123)", testBean, 0, "intValue1", true);
// Integer
- doParse("(integerValue1 == 123)", testBean , 0, "integerValue1", true);
+ doParse("(integerValue1 == 123)", testBean, 0, "integerValue1", true);
// Negative Numbers
- doParse("((intValue2 < -10) and (intValue2 > -60))", numberBean, 0, "intValue2", true);
- doParse("((integerValue2 < -10) and (integerValue2 > -60))", numberBean, 0, "integerValue2", true);
+ doParse("((intValue2 < -10) and (intValue2 > -60))",
+ numberBean,
+ 0,
+ "intValue2",
+ true);
+ doParse("((integerValue2 < -10) and (integerValue2 > -60))",
+ numberBean, 0, "integerValue2", true);
// Hex
- doParse("(integerValue1 == 0x7B)", testBean , 0, "integerValue1", true);
+ doParse("(integerValue1 == 0x7B)",
+ testBean,
+ 0,
+ "integerValue1",
+ true);
// Octal
- doParse("(integerValue1 == 0173)", testBean , 0, "integerValue1", true);
+ doParse("(integerValue1 == 0173)",
+ testBean,
+ 0,
+ "integerValue1",
+ true);
// Test 'String' numbers
PojoBean stringBean = new PojoBean("11", "2");
- doParse("(stringValue1 > stringValue2)", stringBean , 0, "stringValue1", true);
- doParse("(stringValue1 < stringValue2)", stringBean , 0, "stringValue1", false);
+ doParse("(stringValue1 > stringValue2)",
+ stringBean,
+ 0,
+ "stringValue1",
+ true);
+ doParse("(stringValue1 < stringValue2)",
+ stringBean,
+ 0,
+ "stringValue1",
+ false);
}
-
+
/**
* Test Null.
*/
public void testNull() {
-
// Not Null
- doParse("(*this* != null)", testBean , 0, "stringValue1", true);
+ doParse("(*this* != null)", testBean, 0, "stringValue1", true);
// Null
- doParse("(*this* == null)", testBean , 0, "stringValue2", true);
-
-
+ doParse("(*this* == null)", testBean, 0, "stringValue2", true);
}
-
+
/**
* Test Joined expressions ('and' or 'or')
*/
public void testJoined() {
-
// Join with 'or'
- doParse("((*this* == 'ABC') or (stringValue2 == null))", testBean , 0, "stringValue1", true);
- doParse("((*this* != 'ABC') or (stringValue2 == null))", testBean , 0, "stringValue1", true);
- doParse("((*this* == 'ABC') or (stringValue2 != null))", testBean , 0, "stringValue1", true);
- doParse("((*this* != 'ABC') or (stringValue2 != null))", testBean , 0, "stringValue1", false);
+ doParse("((*this* == 'ABC') or (stringValue2 == null))", testBean, 0,
+ "stringValue1", true);
+ doParse("((*this* != 'ABC') or (stringValue2 == null))", testBean, 0,
+ "stringValue1", true);
+ doParse("((*this* == 'ABC') or (stringValue2 != null))", testBean, 0,
+ "stringValue1", true);
+ doParse("((*this* != 'ABC') or (stringValue2 != null))", testBean, 0,
+ "stringValue1", false);
// Join with 'and'
- doParse("((*this* == 'ABC') and (stringValue2 == null))", testBean , 0, "stringValue1", true);
- doParse("((*this* != 'ABC') and (stringValue2 == null))", testBean , 0, "stringValue1", false);
- doParse("((*this* == 'ABC') and (stringValue2 != null))", testBean , 0, "stringValue1", false);
- doParse("((*this* != 'ABC') and (stringValue2 != null))", testBean , 0, "stringValue1", false);
-
+ doParse("((*this* == 'ABC') and (stringValue2 == null))", testBean, 0,
+ "stringValue1", true);
+ doParse("((*this* != 'ABC') and (stringValue2 == null))", testBean, 0,
+ "stringValue1", false);
+ doParse("((*this* == 'ABC') and (stringValue2 != null))", testBean, 0,
+ "stringValue1", false);
+ doParse("((*this* != 'ABC') and (stringValue2 != null))", testBean, 0,
+ "stringValue1", false);
}
-
/**
- * Parse the expression and check that the expected result
- * (either true or false) occurs - fail if an exception is thrown
- * opr the wrong result occurs.
+ * Parse the expression and check that the expected result (either true or
+ * false) occurs - fail if an exception is thrown opr the wrong result
+ * occurs.
*
- * @param test Test expression
- * @param bean Test Bean
- * @param index index value
+ * @param test Test expression
+ * @param bean Test Bean
+ * @param index index value
* @param property Bean property
* @param expected Expected Result
*/
- private void doParse(String test, Object bean, int index, String property, boolean expected) {
+ private void doParse(String test, Object bean, int index, String property,
+ boolean expected) {
boolean result = false;
+
try {
result = doParse(test, bean, index, property);
- } catch (Exception ex) {
- log.error("Parsing " + test + " for property '"+property+"'", ex);
+ }
+ catch (Exception ex) {
+ log.error("Parsing " + test + " for property '" + property + "'",
+ ex);
fail("Parsing " + test + " threw " + ex);
}
+
if (expected) {
assertTrue(test + " didn't return TRUE for " + property, result);
} else {
- assertFalse(test + " didn't return FALSE for " + property, result);
+ assertFalse(test + " didn't return FALSE for " + property,
+ result);
}
}
/**
- * Parse the expression and check that an Exception is throw.
- * Failes if no expection is thrown.
+ * Parse the expression and check that an Exception is throw. Failes if no
+ * expection is thrown.
*
- * @param test Test expression
- * @param bean Test Bean
- * @param index index value
+ * @param test Test expression
+ * @param bean Test Bean
+ * @param index index value
* @param property Bean property
*/
- private void doParseFail(String test, Object bean, int index, String property) {
-
+ private void doParseFail(String test, Object bean, int index,
+ String property) {
try {
boolean result = doParse(test, bean, index, property);
- fail("Parsing " + test + " didn't throw exception as expected " + result);
- } catch (Exception expected) {
+
+ fail("Parsing " + test + " didn't throw exception as expected "
+ + result);
+ }
+ catch (Exception expected) {
// ignore exception - expected result
}
}
@@ -264,31 +290,33 @@
/**
* Parse the expression returning the result
*
- * @param test Test expression
- * @param bean Test Bean
- * @param index index value
+ * @param test Test expression
+ * @param bean Test Bean
+ * @param index index value
* @param property Bean property
*/
- private boolean doParse(String test, Object bean, int index, String property) throws Exception {
-
+ private boolean doParse(String test, Object bean, int index,
+ String property)
+ throws Exception {
if (bean == null) {
- throw new NullPointerException("Bean is null for property '"+property+"'");
+ throw new NullPointerException("Bean is null for property '"
+ + property + "'");
}
- String value = String.class.isInstance(bean)
- ? (String)bean
- : ValidatorUtils.getValueAsString(bean, property);
+ String value = String.class.isInstance(bean) ? (String) bean
+ : ValidatorUtils
+ .getValueAsString(bean, property);
ValidWhenLexer lexer = new ValidWhenLexer(new StringReader(test));
ValidWhenParser parser = new ValidWhenParser(lexer);
+
parser.setForm(bean);
parser.setIndex(index);
parser.setValue(value);
parser.expression();
- return parser.getResult();
+ return parser.getResult();
}
-
}
Modified: struts/action/trunk/xdocs/faqs/actionForm.xml
URL: http://svn.apache.org/viewcvs/struts/action/trunk/xdocs/faqs/actionForm.xml?rev=370938&r1=370937&r2=370938&view=diff
==============================================================================
--- struts/action/trunk/xdocs/faqs/actionForm.xml (original)
+++ struts/action/trunk/xdocs/faqs/actionForm.xml Fri Jan 20 16:19:02 2006
@@ -19,26 +19,31 @@
-->
<document>
-<properties>
- <title>How to Build an Action Form</title>
-</properties>
-
-<body>
-<section name="How to Build an Action Form">
-
-<subsection name="Creating a Login Form">
-
- <p>
- This is a simple example of a login form to illustrate how Struts
- Action Framework makes dealing with forms much less painful than using straight HTML
- and standard JSP facilities.
- Consider the following page (based on the Struts MailReader, found in
- the Application subproject) named <code>logon.jsp</code>:
- </p>
+ <properties>
+ <title>How to Build an Action Form</title>
+ </properties>
+
+ <body>
+ <section name="How to Build an Action Form">
+
+ <subsection name="Creating a Login Form">
+
+ <p>
+ This is a simple example of a login form to illustrate how
+ Struts
+ Action Framework makes dealing with forms much less
+ painful than using straight HTML
+ and standard JSP facilities.
+ Consider the following page (based on the Struts
+ MailReader, found in
+ the Application subproject) named
+ <code>logon.jsp</code>
+ :
+ </p>
-<hr/>
+ <hr/>
-<source><![CDATA[
+ <source><![CDATA[
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
@@ -91,182 +96,260 @@
</html:html>
]]></source>
-<hr/>
+ <hr/>
- <p>
- The following items illustrate the key features of form handling,
- based on this example:
- </p>
-
- <ul>
-
- <li>
- The <code>taglib</code> directive tells the JSP page compiler where to
- find the <em>tag library descriptor</em> for the Struts JSP tags.
- 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
- <strong>message</strong> 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>
- <strong>logon.title</strong> - Title of the logon page
- </li>
-
- <li>
- <strong>prompt.username</strong> - A "Username:" prompt string
- </li>
-
- <li>
- <strong>prompt.password</strong> - A "Password:" prompt string
- </li>
-
- <li>
- <strong>button.submit</strong> - "Submit" for the button label
- </li>
-
- <li>
- <strong>button.reset</strong> - "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 <strong>errors</strong> 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 <strong>form</strong> 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
- <code>ActionForm</code> bean
- [<code>org.apache.struts.action.ActionForm</code>].
- The tag looks up the <code>/logon</code> action mapping in the Struts
- configuration.
- The <code>logon</code> mapping tells the tag that the form bean is
- stored in the session context under the key <code>logonForm</code>.
- The developer provides the Java implementation of the
- ActionForm bean, subclassing the Struts class <code>ActionForm</code>
- (see <a href="../userGuide/building_controller.html#4_3_ActionForm_Classes">Building
- Controller</a> components).
- 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 Java class name specified through the
- action mapping.
- </li>
-
- <li>
- The form bean can also be specified in the tag by providing
- <code>name</code> and <code>type</code> attributes. But most often,
- everything is specified in the
- <a href="../userGuide/building_controller.html#4_8_Writing_Action_Mappings">Struts Configuration
- File</a>.
- </li>
-
- <li>
- The <strong>text</strong> 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 <strong>password</strong> 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 <strong>submit</strong> and<strong>reset</strong> 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>
-
-</subsection>
-
-<subsection name="Transferring Data">
-
- <p>
- To transfer data between ActionForms and business objects,
- many developers use the Commons BeanUtil methods.
- To transfer data from an ActionForm to a business object,
- you can use a statement like:
- </p>
-
-<source><![CDATA[
+ <p>
+ The following items illustrate the key features of form
+ handling,
+ based on this example:
+ </p>
+
+ <ul>
+
+ <li>
+ The
+ <code>taglib</code>
+ directive tells the JSP page compiler where to
+ find the
+ <em>tag library descriptor</em>
+ for the Struts JSP tags.
+ 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
+ <strong>message</strong>
+ 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>
+ <strong>logon.title</strong>
+ - Title of the logon page
+ </li>
+
+ <li>
+ <strong>prompt.username</strong>
+ - A "Username:" prompt string
+ </li>
+
+ <li>
+ <strong>prompt.password</strong>
+ - A "Password:" prompt string
+ </li>
+
+ <li>
+ <strong>button.submit</strong>
+ - "Submit" for the button label
+ </li>
+
+ <li>
+ <strong>button.reset</strong>
+ - "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
+ <strong>errors</strong>
+ 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
+ <strong>form</strong>
+ 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
+ <code>ActionForm</code>
+ bean
+ [
+ <code>org.apache.struts.action.ActionForm</code>
+ ].
+ The tag looks up the
+ <code>/logon</code>
+ action mapping in the Struts
+ configuration.
+ The
+ <code>logon</code>
+ mapping tells the tag that the form bean is
+ stored in the session context under the key
+ <code>logonForm</code>
+ .
+ The developer provides the Java implementation of the
+ ActionForm bean, subclassing the Struts class
+ <code>ActionForm</code>
+ (see
+ <a href="../userGuide/building_controller.html#4_3_ActionForm_Classes">
+ Building
+ Controller</a>
+ components).
+ 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 Java class name specified
+ through the
+ action mapping.
+ </li>
+
+ <li>
+ The form bean can also be specified in the tag by
+ providing
+ <code>name</code>
+ and
+ <code>type</code>
+ attributes. But most often,
+ everything is specified in the
+ <a href="../userGuide/building_controller.html#4_8_Writing_Action_Mappings">
+ Struts Configuration
+ File</a>
+ .
+ </li>
+
+ <li>
+ The
+ <strong>text</strong>
+ 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
+ <strong>password</strong>
+ 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
+ <strong>submit</strong>
+ and
+ <strong>reset</strong>
+ 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>
+
+ </subsection>
+
+ <subsection name="Transferring Data">
+
+ <p>
+ To transfer data between ActionForms and business objects,
+ many developers use the Commons BeanUtil methods.
+ To transfer data from an ActionForm to a business object,
+ you can use a statement like:
+ </p>
+
+ <source><![CDATA[
PropertyUtils.copyProperties(actionForm, businessObject);
]]></source>
-
- <p>
- To transfer data from a business object to an ActionForm,
- you can reverse the parameters
-
-
-<source><![CDATA[
+
+ <p>
+ To transfer data from a business object to an ActionForm,
+ you can reverse the parameters
+
+
+ <source><![CDATA[
PropertyUtils.copyProperties(businessObject, actionForm);
]]></source>
- </p>
-
- <p>
- For more about using this technique, see the
- <a href="http://jakarta.apache.org/commons/beanutils/">
- Jakarta Commons BeanUtils documentation</a>,
- and the Struts MailReader example application.
- </p>
-
- <p>
- Aside from BeanUtils,
- there are other tools available that make it easier to use business objects
- and ActionForms together.
- For more about POJO ActionForms, see the
- <a href="https://formdef.dev.java.net/">FormDef</a> extension
- and the <a href="https://strutslive.dev.java.net/">Struts Live</a> toolkit.
- </p>
-</subsection>
-
-<subsection name="Multipart Forms">
-
- <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>
+ </p>
+
+ <p>
+ For more about using this technique, see the
+ <a href="http://jakarta.apache.org/commons/beanutils/">
+ Jakarta Commons BeanUtils documentation</a>
+ ,
+ and the Struts MailReader example application.
+ </p>
+
+ <p>
+ Aside from BeanUtils,
+ there are other tools available that make it easier to use
+ business objects
+ and ActionForms together.
+ For more about POJO ActionForms, see the
+ <a href="https://formdef.dev.java.net/">FormDef</a>
+ extension
+ and the
+ <a href="https://strutslive.dev.java.net/">Struts Live</a>
+ toolkit.
+ </p>
+ </subsection>
+
+ <subsection name="Multipart Forms">
+
+ <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>
-<source><![CDATA[
+ <source><![CDATA[
<%@page language="java">
-<%@taglib
+<%@taglib
uri="/WEB-INF/struts-html.tld"
prefix="html">
@@ -274,22 +357,22 @@
Please Input Text: <html:text property="myText">
Please Input The File You Wish to Upload: <html:file property="myFile">
-
+
<html:submit />
</html:form>
]]></source>
-<hr/>
+ <hr/>
- <p>
- The next step is to create your ActionForm bean:
- </p>
+ <p>
+ The next step is to create your ActionForm bean:
+ </p>
-<hr/>
+ <hr/>
-<source><![CDATA[
+ <source><![CDATA[
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
@@ -300,19 +383,19 @@
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;
}
@@ -320,27 +403,36 @@
}
]]></source>
-<hr/>
+ <hr/>
- <p>
- Look at the Javadocs for
- <code><a href="../apidocs/org/apache/struts/upload/FormFile.html">
- FormFile</a></code> to see the methods it exposes to manipulate files in
- file uploading.
- Also look at the Javadocs for
- <a href="../apidocs/org/apache/struts/action/ActionServlet.html">
- ActionServlet</a> and
- <a href="../apidocs/org/apache/struts/action/ActionMapping.html">
- ActionMapping</a> for the various parameters you can specify to change
- how files are uploaded.
- Basically in your <code>execute</code> 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>
+ <p>
+ Look at the Javadocs for
+ <code>
+ <a href="../apidocs/org/apache/struts/upload/FormFile.html">
+ FormFile</a>
+ </code>
+ to see the methods it exposes to manipulate files in
+ file uploading.
+ Also look at the Javadocs for
+ <a href="../apidocs/org/apache/struts/action/ActionServlet.html">
+ ActionServlet</a>
+ and
+ <a href="../apidocs/org/apache/struts/action/ActionMapping.html">
+ ActionMapping</a>
+ for the various parameters you can specify to change
+ how files are uploaded.
+ Basically in your
+ <code>execute</code>
+ 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>
-</subsection>
+ </subsection>
- </section>
- </body>
+ </section>
+ </body>
</document>
Modified: struts/action/trunk/xdocs/faqs/apps.xml
URL: http://svn.apache.org/viewcvs/struts/action/trunk/xdocs/faqs/apps.xml?rev=370938&r1=370937&r2=370938&view=diff
==============================================================================
--- struts/action/trunk/xdocs/faqs/apps.xml (original)
+++ struts/action/trunk/xdocs/faqs/apps.xml Fri Jan 20 16:19:02 2006
@@ -18,144 +18,255 @@
-->
<document>
-<properties>
-<title>How to Build Applications</title>
-</properties>
-<body>
-<section name="How to Build Applications">
-<subsection name="About This Document">
-<p>
-This document outlines one possible sequence of development steps that can be followed to create a
-Struts Action Framework application. It is not intended as a complete description of each
-referenced development activity. More detailed documentation is available
-elsewhere and is referenced by "(more...)" links where possible.
-</p>
-</subsection>
+ <properties>
+ <title>How to Build Applications</title>
+ </properties>
+ <body>
+ <section name="How to Build Applications">
+ <subsection name="About This Document">
+ <p>
+ This document outlines one possible sequence of
+ development steps that can be followed to create a
+ Struts Action Framework application. It is not intended as
+ a complete description of each
+ referenced development activity. More detailed
+ documentation is available
+ elsewhere and is referenced by "(more...)" links where
+ possible.
+ </p>
+ </subsection>
-<subsection name="Caveats">
-<ol>
-<li>Requirements development and design are outside of the scope of this document.</li>
-<li>For help installing the framework, see the <a href="../userGuide/installation.html">Getting Started</a> chapter.</li>
-<li>There are many other ways to approach development with the framework and there are many
- other features available besides the ones discussed below. This document
- outlines only one way to get started.</li>
-<li>This document focuses on form/data centric applications, but may also work with
- other types of applications.</li>
-<li>This material was written for Struts 1.1 (beta 2), and reviewed for the 1.2.2 and 1.3.0 releases.</li>
-</ol>
-</subsection>
+ <subsection name="Caveats">
+ <ol>
+ <li>Requirements development and design are outside of the
+ scope of this document.</li>
+ <li>For help installing the framework, see the
+ <a href="../userGuide/installation.html">Getting
+ Started</a>
+ chapter.
+ </li>
+ <li>There are many other ways to approach development with
+ the framework and there are many
+ other features available besides the ones discussed
+ below. This document
+ outlines only one way to get started.</li>
+ <li>This document focuses on form/data centric
+ applications, but may also work with
+ other types of applications.</li>
+ <li>This material was written for Struts 1.1 (beta 2), and
+ reviewed for the 1.2.2 and 1.3.0 releases.</li>
+ </ol>
+ </subsection>
-<subsection name="Overview">
-<ol>
-<li>Implement data entry forms as JSP files.</li>
-<li>Implement one or more <code>ActionForm</code> descendents to buffer data
- between JSPs and Actions.</li>
-<li>Create an XML document that defines the validation rules for your
- application.</li>
-<li>Implement one or more <code>Action</code> descendents to respond form
- submissions.</li>
-<li>Create <code>struts-config.xml</code> to associate forms with
- actions.</li>
-<li>Create or update <code>web.xml</code> to reference
- <code>ActionServlet</code>, taglibs used by the framework.</li>
-<li>Parallel Tasks
-<ol>
-<li>Building</li>
-<li>Unit Testing</li>
-<li>Deployment</li>
-</ol>
-</li>
-</ol>
-</subsection>
+ <subsection name="Overview">
+ <ol>
+ <li>Implement data entry forms as JSP files.</li>
+ <li>Implement one or more
+ <code>ActionForm</code>
+ descendents to buffer data
+ between JSPs and Actions.
+ </li>
+ <li>Create an XML document that defines the validation
+ rules for your
+ application.</li>
+ <li>Implement one or more
+ <code>Action</code>
+ descendents to respond form
+ submissions.
+ </li>
+ <li>Create
+ <code>struts-config.xml</code>
+ to associate forms with
+ actions.
+ </li>
+ <li>Create or update
+ <code>web.xml</code>
+ to reference
+ <code>ActionServlet</code>
+ , taglibs used by the framework.
+ </li>
+ <li>Parallel Tasks
+ <ol>
+ <li>Building</li>
+ <li>Unit Testing</li>
+ <li>Deployment</li>
+ </ol>
+ </li>
+ </ol>
+ </subsection>
-<subsection name="Details">
-<ol>
-<li>Implement data entry forms as JSP files.
-<ol>
-<li>Use elements from the <code>html</code> taglib
- to define the form elements. <a href="http://struts.apache.org/struts-taglib/tagreference-struts-bean.html">
- (more...)</a></li>
-<li>Use <code>message</code> and other elements from the <code>bean</code>
- taglib to define the labels and other static text of the form.
- <a href="http://struts.apache.org/struts-taglib/tagreference-struts-bean.html">(more...)</a>
-<ol>
-<li>Create and maintain a properties file of the text elements
- to be displayed. <a href="../userGuide/preface.html#0_6_Properties_Files_and_ResourceBundles">(more...)
- </a></li>
-</ol>
-</li>
-<li>Use <code>property</code> attributes to link form fields to
- <code>ActionForm</code> instance variables.</li>
-</ol>
-</li>
-<li>Implement one or more <code>ActionForm</code> descendents
- to buffer data between JSPs and Actions.
-<ol>
-<li>Create get/set pairs that correspond to the property names
- in your related JSP form. Example:
-<pre><html:text property="city" /></pre>
- needs:
-<pre>getCity() and setCity(String c)</pre>
-</li>
-<li>When needed, create a <code>reset</code> method
- that sets the fields of the <code>ActionForm</code> to their default values. Most ActionForms do not need to do this.</li>
-</ol>
-</li>
-<li>Create an XML document that defines the validation rules for your
- application.</li>
-<li>Implement one or more <code>Action</code> descendents
- to respond to form submissions.
-<ol>
-<li>Descend from DispatchAction or LookupDispatchAction if you
- want one class to handle more than one kind of event (example: one Action
- to handle 'insert', 'update' and 'delete' events, using a different "surrogate" execute method for each). <a href="http://husted.com/struts/tips/002.html">(more...)</a></li>
-<li>Use the <code>execute</code> method
- (or its surrogates) of your Action class to interface with objects in your
- application responsible for database interaction, such as EJBs, etc.
- <!-- [:TODO: find good doc to link to] -->
-</li>
-<li>Use the return value of the <code>execute</code> method
- (or its surrogates) direct the user interface to the appropriate next page.
-<!-- [:TODO: find good doc to link to] -->
-</li>
-</ol>
-</li>
-<li>Create <code>struts-config.xml</code> to
- associate forms with actions. The file minimally needs:</li>
-<li>Create or update <code>web.xml</code> to
- reference <code>ActionServlet</code>, taglibs used by Struts. <a href="../userGuide/configuration.html#5_4_The_Web_Application_Deployment_Descriptor"> (more...)</a></li>
-<li>Parallel Tasks
-<ol>
-<li>Building
-<ol>
-<li>Use Ant. It can compile, create WAR file, perform XSLT
- transformations, run unit tests, interact with version control systems,
- clean up, etc. <a href="http://jakarta.apache.org/ant"> (more...)</a></li>
-<li>Create and use build script incrementally, as you create
- files that need to be copied, compiled, etc. </li>
-</ol>
-</li>
-<li>Unit Testing
-<ol>
-<li>Unit test normal java beans with JUnit. <a href="http://www.junit.org"> (more...)</a></li>
-<li>Unit test JSP, taglibs and conventional servlet components
- with Cactus. <a href="http://jakarta.apache.org/cactus"> (more...)</a></li>
-<li>Unit test Action servlets with StrutsTestCase. <a href="http://strutstestcase.sourceforge.net"> (more...)</a></li>
-<li>Add all unit tests to the build script as a separate
- target. This target should use the <code>junit</code> tag to launch each TestCase descendent. <a href="http://jakarta.apache.org/ant/manual/OptionalTasks/junit.html"> (more...)</a></li>
-</ol>
-</li>
-<li>Deployment
-<ol>
-<li>Build script should create a war file containing the
- files developed above, along with files that make up the Struts framework.
- <!-- [:TODO: describe this further, look for doc to link to] -->
-</li>
-</ol>
-</li>
-</ol>
-</li>
-</ol></subsection>
-</section>
-</body>
+ <subsection name="Details">
+ <ol>
+ <li>Implement data entry forms as JSP files.
+ <ol>
+ <li>Use elements from the
+ <code>html</code>
+ taglib
+ to define the form elements.
+ <a href="http://struts.apache.org/struts-taglib/tagreference-struts-bean.html">
+ (more...)</a>
+ </li>
+ <li>Use
+ <code>message</code>
+ and other elements from the
+ <code>bean</code>
+ taglib to define the labels and other static
+ text of the form.
+ <a href="http://struts.apache.org/struts-taglib/tagreference-struts-bean.html">
+ (more...)</a>
+ <ol>
+ <li>Create and maintain a properties file
+ of the text elements
+ to be displayed.
+ <a href="../userGuide/preface.html#0_6_Properties_Files_and_ResourceBundles">
+ (more...)
+ </a>
+ </li>
+ </ol>
+ </li>
+ <li>Use
+ <code>property</code>
+ attributes to link form fields to
+ <code>ActionForm</code>
+ instance variables.
+ </li>
+ </ol>
+ </li>
+ <li>Implement one or more
+ <code>ActionForm</code>
+ descendents
+ to buffer data between JSPs and Actions.
+ <ol>
+ <li>Create get/set pairs that correspond to the
+ property names
+ in your related JSP form. Example:
+ <pre><html:text property="city" /></pre>
+ needs:
+ <pre>getCity() and setCity(String c)</pre>
+ </li>
+ <li>When needed, create a
+ <code>reset</code>
+ method
+ that sets the fields of the
+ <code>ActionForm</code>
+ to their default values. Most ActionForms do
+ not need to do this.
+ </li>
+ </ol>
+ </li>
+ <li>Create an XML document that defines the validation
+ rules for your
+ application.</li>
+ <li>Implement one or more
+ <code>Action</code>
+ descendents
+ to respond to form submissions.
+ <ol>
+ <li>Descend from DispatchAction or
+ LookupDispatchAction if you
+ want one class to handle more than one kind of
+ event (example: one Action
+ to handle 'insert', 'update' and 'delete'
+ events, using a different "surrogate" execute
+ method for each).
+ <a href="http://husted.com/struts/tips/002.html">
+ (more...)</a>
+ </li>
+ <li>Use the
+ <code>execute</code>
+ method
+ (or its surrogates) of your Action class to
+ interface with objects in your
+ application responsible for database
+ interaction, such as EJBs, etc.
+ <!-- [:TODO: find good doc to link to] -->
+ </li>
+ <li>Use the return value of the
+ <code>execute</code>
+ method
+ (or its surrogates) direct the user interface
+ to the appropriate next page.
+ <!-- [:TODO: find good doc to link to] -->
+ </li>
+ </ol>
+ </li>
+ <li>Create
+ <code>struts-config.xml</code>
+ to
+ associate forms with actions. The file minimally
+ needs:
+ </li>
+ <li>Create or update
+ <code>web.xml</code>
+ to
+ reference
+ <code>ActionServlet</code>
+ , taglibs used by Struts.
+ <a href="../userGuide/configuration.html#5_4_The_Web_Application_Deployment_Descriptor">
+ (more...)</a>
+ </li>
+ <li>Parallel Tasks
+ <ol>
+ <li>Building
+ <ol>
+ <li>Use Ant. It can compile, create WAR
+ file, perform XSLT
+ transformations, run unit tests,
+ interact with version control systems,
+ clean up, etc.
+ <a href="http://jakarta.apache.org/ant">
+ (more...)</a>
+ </li>
+ <li>Create and use build script
+ incrementally, as you create
+ files that need to be copied,
+ compiled, etc.</li>
+ </ol>
+ </li>
+ <li>Unit Testing
+ <ol>
+ <li>Unit test normal java beans with
+ JUnit.
+ <a href="http://www.junit.org">
+ (more...)</a>
+ </li>
+ <li>Unit test JSP, taglibs and
+ conventional servlet components
+ with Cactus.
+ <a href="http://jakarta.apache.org/cactus">
+ (more...)</a>
+ </li>
+ <li>Unit test Action servlets with
+ StrutsTestCase.
+ <a href="http://strutstestcase.sourceforge.net">
+ (more...)</a>
+ </li>
+ <li>Add all unit tests to the build script
+ as a separate
+ target. This target should use the
+ <code>junit</code>
+ tag to launch each TestCase
+ descendent.
+ <a href="http://jakarta.apache.org/ant/manual/OptionalTasks/junit.html">
+ (more...)</a>
+ </li>
+ </ol>
+ </li>
+ <li>Deployment
+ <ol>
+ <li>Build script should create a war file
+ containing the
+ files developed above, along with
+ files that make up the Struts
+ framework.
+ <!-- [:TODO: describe this further, look for doc to link to] -->
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </subsection>
+ </section>
+ </body>
</document>
Modified: struts/action/trunk/xdocs/faqs/db-howto.xml
URL: http://svn.apache.org/viewcvs/struts/action/trunk/xdocs/faqs/db-howto.xml?rev=370938&r1=370937&r2=370938&view=diff
==============================================================================
--- struts/action/trunk/xdocs/faqs/db-howto.xml (original)
+++ struts/action/trunk/xdocs/faqs/db-howto.xml Fri Jan 20 16:19:02 2006
@@ -18,202 +18,315 @@
-->
<document>
- <properties>
- <title>How to Access a Database</title>
- </properties>
-
-<body>
-
-<section name="How to Access a Database" href="database">
-
- <p>
- Most developers would consider accessing a database part of the "business
- end" of an application. Most often, we don't access a databse for the sake
- of accessing a database. We use the database as part of a larger business
- transaction. So lets start with accessing business logic from Struts.
- </p>
-
- <p>
- The best thing is use the Action as a thin adaptor between the
- web/presentation-tier and your business classes (including those that
- access a database).
- </p>
-
- <p>
- So you first design a business API that uses plain Java classes.
- The best thing is to use objects that take ordinary Java types and return
- a JavaBean or collection of JavaBeans.
- The Action then calls these objects and passes the result back to the
- web/presentation tier.
- </p>
-
- <p>
- A common approach is to create an Action class for each of business
- transaction, or use case, in your application. A simple "CRUD"
- application might have a CreateAction, a RetrieveAction, an UpdateAction,
- and a DeleteAction. To complete each transaction, the Action can make
- whatever calls are needed to your business API classes.
- </p>
-
- <p>
- Ideally, all the database access code should be encapsulated behind the
- business API classes, so Struts doesn't know what persistent layer you
- are using (or even if there is a persistence layer).
- It just passes a key or search String and gets back a bean or collection
- of beans.
- This lets you use the same business API classes in other environments,
- and also to run unit tests against your business API outside of Struts or
- a HTTP environment.
- </p>
-
- <p>
- The Struts MailReader (see the Struts Applications subproject) shows
- how this is usually done. MailReader uses the DAO (Data Access Object)
- pattern to separate the persistence layer from the (Struts) control layer.
- MailReader defines a DAO interface that the Actions can call, it then
- defines a implementation that uses a database stored in main memory.
- Other implementations could be defined and used instead, without
- changing any of the Struts Action classes.
- </p>
-
- <p>
- To get started, it's simplest to setup a 1:1 correspondence between the
- Actions and your application's use cases. Each use case may make one or
- more calls to your business API, but from the user's perspective, each
- use case is a single transaction.
- </p>
-
- <p>
- As you gain experience, you will find ways to combine your Action classes,
- say by using the DispatchAction.
- It's even possible to use a single "framework" Action to call all of your
- business classes, as is done with Scaffold ProcessAction in the Sandbox
- subproject.
- </p>
-
- <p>
- Using fewer Actions does require a deeper understanding of how Struts
- and MVC frameworks operate.
- Don't hesitate to err on the side of creating more Action classes at first.
- The configuration file makes it easy to refactor your Actions later,
- since you can change the Action type without changing anything else in the
- application.
- </p>
-
- </section>
-
- <section name="Using DataSources" href="datasources">
-
- <p>
- When you use the DAO approach, all of the database access details are
- hidden behind the business interface. The implementation of the business
- classes handle all the gritty details, like using a <code>DataSource</code>
- to pool connections to the database.
- </p>
-
- <p>
- As a rule, you should always use a connection pool to access a database.
- The <code>DataSource</code> interface is the preferred way to implement a
- connection pool today. Many containers and database systems now bundle
- a DataSource implmentation that you can use. Most often, the DataSource
- is made available through JNDI. The JNDI approach makes it easy for your
- business classes to access the DataSource without worrying about who set it
- up.
- </p>
-
- </section>
-
- <section name="Persistence Franeworks" href="persistence">
-
- <p>
- There are many useful and mature persistence layer frameworks available.
- Before using raw JDBC or "rolling your own" solution, you should carefully
- review one or more of these packages. Here's a short list of packages
- most often mentioned on the Struts User list:
- </p>
-
- <ul>
- <li><a href="http://www.hibernate.org/">Hibernate</a></li>
- <li><a href="http://sourceforge.net/projects/ibatisdb">iBATIS</a></li>
- <li><a href="http://db.apache.org/ojb/">Object Relational Bridge</a></li>
- <li><a href="http://db.apache.org/torque/index.html">Torque / Peers</a></li>
- </ul>
-
- <p>
- For more, see the
- <a href="http://struts.sourceforge.net/community/models.html">Struts
- Community Resources area</a> on SourceForge.
- </p>
-
- </section>
-
-
-<section href="more" name="See Also">
-
- <p>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html</a>
- </p>
-
- <p>
- Transformation/Data Transfer<br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html</a><br/>
- <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html</a>
- </p>
-
-</section>
-
-
-<section href="DynaResultSet" name="Rendering a dynamic result set">
-
- <p>
- The result of most queries will map to the ActionForms you are already using,
- and so you can render the ResultSet as a collection of ActionForms.
- But sometimes there are columns in a ResultSet that are not properties of an ActionForm,
- or even known in advance.
- </p>
-
- <p>
- Happily, the Struts JSP tags don't care what type of bean you use with them.
- You could even output a ResultSet directly.
- But a ResultSet retains a connection to the database, and passing "all that" directly to a JSP gets messy.
- So what's a developer to do?
- </p>
-
- <p>
- Since Struts 1.1, the simplest option is to use a
- <a href="http://jakarta.apache.org/commons/beanutils/api/org/apache/commons/beanutils/ResultSetDynaClass.html">ResultSetDynaClass</a>
- to transfer the ResultSet into an ArrayList of DynaBeans.
- The Struts custom tags can use DynaBean properties as easily as they use conventional JavaBean properties.
- (See <strong>DynaActionForm classes</strong> in the Struts User Guide for details.)
- </p>
-
- <p>
- Since this is in the BeanUtils jar, you already have it on board, and just need to implement the transfer routine
- (see the ResultSetDynaClass link).
- </p>
+ <properties>
+ <title>How to Access a Database</title>
+ </properties>
+
+ <body>
+
+ <section name="How to Access a Database" href="database">
+
+ <p>
+ Most developers would consider accessing a database part of
+ the "business
+ end" of an application. Most often, we don't access a databse
+ for the sake
+ of accessing a database. We use the database as part of a
+ larger business
+ transaction. So lets start with accessing business logic from
+ Struts.
+ </p>
+
+ <p>
+ The best thing is use the Action as a thin adaptor between the
+ web/presentation-tier and your business classes (including
+ those that
+ access a database).
+ </p>
+
+ <p>
+ So you first design a business API that uses plain Java
+ classes.
+ The best thing is to use objects that take ordinary Java types
+ and return
+ a JavaBean or collection of JavaBeans.
+ The Action then calls these objects and passes the result back
+ to the
+ web/presentation tier.
+ </p>
+
+ <p>
+ A common approach is to create an Action class for each of
+ business
+ transaction, or use case, in your application. A simple "CRUD"
+ application might have a CreateAction, a RetrieveAction, an
+ UpdateAction,
+ and a DeleteAction. To complete each transaction, the Action
+ can make
+ whatever calls are needed to your business API classes.
+ </p>
+
+ <p>
+ Ideally, all the database access code should be encapsulated
+ behind the
+ business API classes, so Struts doesn't know what persistent
+ layer you
+ are using (or even if there is a persistence layer).
+ It just passes a key or search String and gets back a bean or
+ collection
+ of beans.
+ This lets you use the same business API classes in other
+ environments,
+ and also to run unit tests against your business API outside
+ of Struts or
+ a HTTP environment.
+ </p>
+
+ <p>
+ The Struts MailReader (see the Struts Applications subproject)
+ shows
+ how this is usually done. MailReader uses the DAO (Data Access
+ Object)
+ pattern to separate the persistence layer from the (Struts)
+ control layer.
+ MailReader defines a DAO interface that the Actions can call,
+ it then
+ defines a implementation that uses a database stored in main
+ memory.
+ Other implementations could be defined and used instead,
+ without
+ changing any of the Struts Action classes.
+ </p>
+
+ <p>
+ To get started, it's simplest to setup a 1:1 correspondence
+ between the
+ Actions and your application's use cases. Each use case may
+ make one or
+ more calls to your business API, but from the user's
+ perspective, each
+ use case is a single transaction.
+ </p>
+
+ <p>
+ As you gain experience, you will find ways to combine your
+ Action classes,
+ say by using the DispatchAction.
+ It's even possible to use a single "framework" Action to call
+ all of your
+ business classes, as is done with Scaffold ProcessAction in
+ the Sandbox
+ subproject.
+ </p>
+
+ <p>
+ Using fewer Actions does require a deeper understanding of how
+ Struts
+ and MVC frameworks operate.
+ Don't hesitate to err on the side of creating more Action
+ classes at first.
+ The configuration file makes it easy to refactor your Actions
+ later,
+ since you can change the Action type without changing anything
+ else in the
+ application.
+ </p>
+
+ </section>
+
+ <section name="Using DataSources" href="datasources">
+
+ <p>
+ When you use the DAO approach, all of the database access
+ details are
+ hidden behind the business interface. The implementation of
+ the business
+ classes handle all the gritty details, like using a
+ <code>DataSource</code>
+ to pool connections to the database.
+ </p>
+
+ <p>
+ As a rule, you should always use a connection pool to access a
+ database.
+ The
+ <code>DataSource</code>
+ interface is the preferred way to implement a
+ connection pool today. Many containers and database systems
+ now bundle
+ a DataSource implmentation that you can use. Most often, the
+ DataSource
+ is made available through JNDI. The JNDI approach makes it
+ easy for your
+ business classes to access the DataSource without worrying
+ about who set it
+ up.
+ </p>
+
+ </section>
+
+ <section name="Persistence Franeworks" href="persistence">
+
+ <p>
+ There are many useful and mature persistence layer frameworks
+ available.
+ Before using raw JDBC or "rolling your own" solution, you
+ should carefully
+ review one or more of these packages. Here's a short list of
+ packages
+ most often mentioned on the Struts User list:
+ </p>
+
+ <ul>
+ <li>
+ <a href="http://www.hibernate.org/">Hibernate</a>
+ </li>
+ <li>
+ <a href="http://sourceforge.net/projects/ibatisdb">
+ iBATIS</a>
+ </li>
+ <li>
+ <a href="http://db.apache.org/ojb/">Object Relational
+ Bridge</a>
+ </li>
+ <li>
+ <a href="http://db.apache.org/torque/index.html">Torque /
+ Peers</a>
+ </li>
+ </ul>
+
+ <p>
+ For more, see the
+ <a href="http://struts.sourceforge.net/community/models.html">
+ Struts
+ Community Resources area</a>
+ on SourceForge.
+ </p>
+
+ </section>
+
+
+ <section href="more" name="See Also">
+
+ <p>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html</a>
+ </p>
+
+ <p>
+ Transformation/Data Transfer
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html</a>
+ <br/>
+ <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html">
+ http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html</a>
+ </p>
+
+ </section>
+
+
+ <section href="DynaResultSet" name="Rendering a dynamic result set">
+
+ <p>
+ The result of most queries will map to the ActionForms you are
+ already using,
+ and so you can render the ResultSet as a collection of
+ ActionForms.
+ But sometimes there are columns in a ResultSet that are not
+ properties of an ActionForm,
+ or even known in advance.
+ </p>
+
+ <p>
+ Happily, the Struts JSP tags don't care what type of bean you
+ use with them.
+ You could even output a ResultSet directly.
+ But a ResultSet retains a connection to the database, and
+ passing "all that" directly to a JSP gets messy.
+ So what's a developer to do?
+ </p>
+
+ <p>
+ Since Struts 1.1, the simplest option is to use a
+ <a href="http://jakarta.apache.org/commons/beanutils/api/org/apache/commons/beanutils/ResultSetDynaClass.html">
+ ResultSetDynaClass</a>
+ to transfer the ResultSet into an ArrayList of DynaBeans.
+ The Struts custom tags can use DynaBean properties as easily
+ as they use conventional JavaBean properties.
+ (See
+ <strong>DynaActionForm classes</strong>
+ in the Struts User Guide for details.)
+ </p>
+
+ <p>
+ Since this is in the BeanUtils jar, you already have it on
+ board, and just need to implement the transfer routine
+ (see the ResultSetDynaClass link).
+ </p>
-</section>
+ </section>
-</body>
+ </body>
</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org