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/02/10 22:09:58 UTC
svn commit: r376854 [5/5] - in /struts/taglib/trunk:
src/java/org/apache/struts/taglib/ src/webapp/WEB-INF/
src/webapp/org/apache/struts/taglib/logic/ xdocs/
Modified: struts/taglib/trunk/xdocs/indexedprops.xml
URL: http://svn.apache.org/viewcvs/struts/taglib/trunk/xdocs/indexedprops.xml?rev=376854&r1=376853&r2=376854&view=diff
==============================================================================
--- struts/taglib/trunk/xdocs/indexedprops.xml (original)
+++ struts/taglib/trunk/xdocs/indexedprops.xml Fri Feb 10 13:09:57 2006
@@ -18,381 +18,558 @@
-->
<document>
- <properties>
- <title>Indexed Properties, Mapped Properties, and Indexed Tags</title>
- </properties>
- <body>
- <section name="Indexed Properties, Mapped Properties, and Indexed Tags">
- <subsection name="Introduction">
- <p>
- The JSP specification discusses using "indexed properties" in reference to
- the <jsp:setProperty> tag. However, none of the support provided in
- the base JSP specification actually deals with the "indexing" part. In
- truth, it allows for setting "array properties", but it doesn't do much
- for setting or even getting the actual values in each entry of the array,
- except with explicit JSP expressions (<%= %>).
- </p>
- <p>
- The Struts framework provides much more powerful features related to
- indexed properties, but in truth most of the heavy lifting is not even in
- the Struts framework, but in the Jakarta Commons Beanutils package. This
- package is used by Struts to provide this functionality. You can see the
- javadoc documentation for the Beanutils package at <a
- href="http://jakarta.apache.org/commons/beanutils/api/index.html">http://jakarta.apache.org/commons/beanutils/api/index.html</a>.
- The information particularly related to indexed properties is in the
- package description for the org.apache.commons.beanutils package. This
- article mirrors that information, but focuses on how this functionality is
- mapped to JSP tags using the Struts tag library.
- </p>
- <p>
- The support for indexed properties also includes "mapped properties",
- "nested properties" and "indexed tags", which are all related but slightly
- different. The latter is exclusive to Struts, but the first two are also
- provided by the Beanutils package. This article will cover all three of
- these topics.
- </p>
- </subsection>
- <subsection name="Indexed Properties">
- <p>
- The simplest demonstration of using indexed properties in Struts can be
- shown with the following simple bean and JSP page:
- </p>
- <pre>
-package org.apache.struts.webapp.exercise;
-import org.apache.struts.action.ActionForm;
-public class StringBean extends ActionForm {
- private String strAry[] = { "String 0", "String 1", "String 2", "String 3", "String 4" };
+ <properties>
+ <title>Indexed Properties, Mapped Properties, and Indexed Tags</title>
+ </properties>
+ <body>
+ <section
+ name="Indexed Properties, Mapped Properties, and Indexed Tags">
+ <subsection name="Introduction">
+ <p>
+ The JSP specification discusses using "indexed properties"
+ in reference to
+ the <jsp:setProperty> tag. However, none of the
+ support provided in
+ the base JSP specification actually deals with the
+ "indexing" part. In
+ truth, it allows for setting "array properties", but it
+ doesn't do much
+ for setting or even getting the actual values in each
+ entry of the array,
+ except with explicit JSP expressions (<%= %>).
+ </p>
+ <p>
+ The Struts framework provides much more powerful features
+ related to
+ indexed properties, but in truth most of the heavy lifting
+ is not even in
+ the Struts framework, but in the Jakarta Commons Beanutils
+ package. This
+ package is used by Struts to provide this functionality.
+ You can see the
+ javadoc documentation for the Beanutils package at
+ <a
+ href="http://jakarta.apache.org/commons/beanutils/api/index.html">
+ http://jakarta.apache.org/commons/beanutils/api/index.html</a>
+ .
+ The information particularly related to indexed properties
+ is in the
+ package description for the org.apache.commons.beanutils
+ package. This
+ article mirrors that information, but focuses on how this
+ functionality is
+ mapped to JSP tags using the Struts tag library.
+ </p>
+ <p>
+ The support for indexed properties also includes "mapped
+ properties",
+ "nested properties" and "indexed tags", which are all
+ related but slightly
+ different. The latter is exclusive to Struts, but the
+ first two are also
+ provided by the Beanutils package. This article will cover
+ all three of
+ these topics.
+ </p>
+ </subsection>
+ <subsection name="Indexed Properties">
+ <p>
+ The simplest demonstration of using indexed properties in
+ Struts can be
+ shown with the following simple bean and JSP page:
+ </p>
+ <pre>
+ package org.apache.struts.webapp.exercise;
+ import org.apache.struts.action.ActionForm;
+ public class StringBean extends ActionForm {
+ private String strAry[] = { "String 0", "String 1",
+ "String 2", "String 3", "String 4" };
- public String getStringIndexed(int index) {
- return strAry[index];
- }
-
- public void setStringIndexed(int index, String value) {
- strAry[index] = value;
- }
-}</pre>
- <p>
- First note the two methods in the StringBean class, "getStringIndexed()"
- and "setStringIndexed()". Note that the "get" method takes an "int" and
- the "set" method takes an "int" and "String". The Beanutils package and
- Struts recognizes this arrangement of signatures as an "indexed property",
- in this case with the property name "stringIndexed".
- </p>
- <pre>
-<!-- indexedtest.jsp -->
-<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
-<jsp:useBean id="bean" class="org.apache.struts.webapp.exercise.StringBean"/>
-<bean:write name="bean" property="stringIndexed[1]"/></pre>
- <p>
- Note the property value of "stringIndexed[1]". This is intended to
- reference the indexed property "stringIndexed", and the 1st (zero-based)
- entry of whatever array or collection which the indexed property
- represents.
- </p>
- <p>
- As you might be able to guess, when this page is executed, it will print
- just the string "String 1", which is the corresponding array entry at that
- index value.
- </p>
- <p>
- This is a simple demonstration of what indexed properties can provide.
- </p>
- </subsection>
- <subsection name="List-Backed Indexed Properties">
- <p>
- A variation on indexed properties are properties whose type is
- <code>java.util.List</code> or a subclass.
- </p>
- <p>
- For instance, the first example using "StringBean.java" and
- "indexedtest.jsp" could use a modified "StringBean.java" class, like this:
- </p>
- <pre>
-package org.apache.struts.webapp.exercise;
-import org.apache.struts.action.ActionForm;
-public class StringBean2 extends ActionForm {
- private String strAry[] = { "String 0", "String 1", "String 2", "String 3", "String 4" };
+ public String getStringIndexed(int index) {
+ return strAry[index];
+ }
- public java.util.List getStringIndexed() {
- return java.util.Arrays.asList(strAry);
- }
-}</pre>
- <p>
- Note the different implementation of the "getStringIndexed()" method,
- returning a List instead of a String. If this bean class is substituted
- with the original "indexedtest.jsp", the result will be identical.
- </p>
- </subsection>
- <subsection name="Mapped Properties">
- <p>
- The idea of "mapped properties" as opposed to "indexed properties" is that
- the property represents a "map" type, as opposed to an array or collection
- type. The signature of the "get" and "set" methods for a mapped property
- are different from the same methods for an indexed property. In
- particular, instead of an "int" for the index, there is a "String" for the
- key.
- </p>
- <p>
- The previous example for indexed properties can be changed to the
- following to demonstrate mapped properties:
- </p>
- <pre>
-package org.apache.struts.webapp.exercise;
-import java.util.HashMap;
-import org.apache.struts.action.ActionForm;
-public class StringBean3 extends ActionForm {
- private String strAry[] = { "String 0", "String 1", "String 2", "String 3", "String 4" };
-
- private HashMap map = new HashMap();
+ public void setStringIndexed(int index, String value) {
+ strAry[index] = value;
+ }
+ }</pre>
+ <p>
+ First note the two methods in the StringBean class,
+ "getStringIndexed()"
+ and "setStringIndexed()". Note that the "get" method takes
+ an "int" and
+ the "set" method takes an "int" and "String". The
+ Beanutils package and
+ Struts recognizes this arrangement of signatures as an
+ "indexed property",
+ in this case with the property name "stringIndexed".
+ </p>
+ <pre>
+ <!-- indexedtest.jsp -->
+ <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"
+ %>
+ <jsp:useBean id="bean"
+ class="org.apache.struts.webapp.exercise.StringBean"/>
+ <bean:write name="bean" property="stringIndexed[1]"/></pre>
+ <p>
+ Note the property value of "stringIndexed[1]". This is
+ intended to
+ reference the indexed property "stringIndexed", and the
+ 1st (zero-based)
+ entry of whatever array or collection which the indexed
+ property
+ represents.
+ </p>
+ <p>
+ As you might be able to guess, when this page is executed,
+ it will print
+ just the string "String 1", which is the corresponding
+ array entry at that
+ index value.
+ </p>
+ <p>
+ This is a simple demonstration of what indexed properties
+ can provide.
+ </p>
+ </subsection>
+ <subsection name="List-Backed Indexed Properties">
+ <p>
+ A variation on indexed properties are properties whose
+ type is
+ <code>java.util.List</code>
+ or a subclass.
+ </p>
+ <p>
+ For instance, the first example using "StringBean.java"
+ and
+ "indexedtest.jsp" could use a modified "StringBean.java"
+ class, like this:
+ </p>
+ <pre>
+ package org.apache.struts.webapp.exercise;
+ import org.apache.struts.action.ActionForm;
+ public class StringBean2 extends ActionForm {
+ private String strAry[] = { "String 0", "String 1",
+ "String 2", "String 3", "String 4" };
- public StringBean() {
- map.put("zero", strAry[0]);
- map.put("one", strAry[1]);
- map.put("two", strAry[2]);
- map.put("three", strAry[3]);
- map.put("four", strAry[4]);
- }
+ public java.util.List getStringIndexed() {
+ return java.util.Arrays.asList(strAry);
+ }
+ }</pre>
+ <p>
+ Note the different implementation of the
+ "getStringIndexed()" method,
+ returning a List instead of a String. If this bean class
+ is substituted
+ with the original "indexedtest.jsp", the result will be
+ identical.
+ </p>
+ </subsection>
+ <subsection name="Mapped Properties">
+ <p>
+ The idea of "mapped properties" as opposed to "indexed
+ properties" is that
+ the property represents a "map" type, as opposed to an
+ array or collection
+ type. The signature of the "get" and "set" methods for a
+ mapped property
+ are different from the same methods for an indexed
+ property. In
+ particular, instead of an "int" for the index, there is a
+ "String" for the
+ key.
+ </p>
+ <p>
+ The previous example for indexed properties can be changed
+ to the
+ following to demonstrate mapped properties:
+ </p>
+ <pre>
+ package org.apache.struts.webapp.exercise;
+ import java.util.HashMap;
+ import org.apache.struts.action.ActionForm;
+ public class StringBean3 extends ActionForm {
+ private String strAry[] = { "String 0", "String 1",
+ "String 2", "String 3", "String 4" };
- public Object getStringMapped(String key) {
- return map.get(key);
- }
-
- public void setStringMapped(String key, Object value) {
- map.put(key, value);
- }
-}</pre>
- <p>
- Note the "get" and "set" methods to represent the mapped property.
- </p>
- <pre>
-<!-- indexedtest3.jsp -->
-<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
-<jsp:useBean id="bean" class="org.apache.struts.webapp.exercise.StringBean"/>
-<bean:write name="bean" property="stringMapped(two)"/></pre>
- <p>
- Note the property value of "stringMapped(two)". This will reference the
- mapped property "stringMapped", using the key value of "two".
- </p>
- <p>
- When this page is executed, it will print just the string "String 2",
- which is the string stored in the HashMap with the key "two".
- </p>
- </subsection>
- <subsection name="Nested Properties">
- <p>
- Nested properties allows you to combine normal properties, indexed
- properties, and mapped properties in a hierarchical fashion. A property
- value of a bean does not have to be a primitive like "int" or "String.
- The property value can be a bean with its own properties. The following
- example demonstrates this.
- </p>
- <pre>
-package org.apache.struts.webapp.exercise;
-import org.apache.struts.util.LabelValueBean;
-import org.apache.struts.action.ActionForm;
-public class StringBean4 extends ActionForm {
- private LabelValueBean[] lvbeans;
-
- public StringBean() {
- lvbeans = new LabelValueBean[5];
- lvbeans[0] = new LabelValueBean("Zero", 0+"");
- lvbeans[1] = new LabelValueBean("One", 1+"");
- lvbeans[2] = new LabelValueBean("Two", 2+"");
- lvbeans[3] = new LabelValueBean("Three", 3+"");
- lvbeans[4] = new LabelValueBean("Four", 4+"");
- }
+ private HashMap map = new HashMap();
- public LabelValueBean getLabelValue(int index) {
- return lvbeans[index];
- }
-}</pre>
- <p>
- First note the use of the class "LabelValueBean". This is a simple class
- provided in the Struts library which represents a pair of two Strings, a
- "label" and a "value". It itself is a bean, providing these two
- properties with standard getters and setter methods.
- </p>
- <p>
- Then, see the "getLabelValue()" method, representing the indexed property
- "labelValue". This class doesn't show a "setter" method. If you only ever
- provide read-only access a property, then it is not necessary to provide a
- setter method.
- </p>
- <pre>
-<!-- indexedtest4.jsp -->
-<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
-<jsp:useBean id="bean" class="org.apache.struts.webapp.exercise.StringBean"/>
-<bean:write name="bean" property="labelValue[1].label"/></pre>
- <p>
- Note here the "nested" property reference. It is first using the indexed
- property "labelValue" and then the "normal" property of the LabelValueBean
- to get the final result. When this page is executed, it will print the
- string "One", representing the "label" property of the 1st entry of the
- array represented by the "labelValue" indexed property.
- </p>
- </subsection>
- <subsection name="Dynamic Indexes for Indexed Properties">
- <p>
- When people started using indexed properties in Struts tags, I'm
- reasonably certain they started out with a high level of enthusiasm, but
- were somewhat frustrated when they discovered reality. The reality is
- that the "index" for indexed properties often needs to be a dynamic value,
- usually from the "indexId" counter in the "<logic:iterate>" tag.
- </p>
- <p>
- For instance, the following example JSP page using the same "StringBean"
- bean class uses a dynamic value for the index:
- </p>
- <pre>
-<!-- indexedtest5.jsp -->
-<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
-<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
-<html>
- <body>
- <html:form action="indexedtest5.do">
- <logic:iterate name="stringbean" property="stringArray" id="foo"
- indexId="ctr">
- <html:text name="stringbean"
- property='<%= "labelValue[" + ctr + "].label" %>' />
- </logic:iterate>
- <html:submit property="submitValue">Submit Changes</html:submit>
- </html:form>
- </body>
-</html></pre>
- <p>
- The JSP expression syntax for the <code>property</code> attribute is somewhat
- messy and easy to get wrong so it's something we want to avoid. One
- way to make this a little cleaner is to use "indexed tags", but there's a
- wrinkle to this approach. We'll first cover the details of indexed tags,
- then we'll talk about the wrinkle, and then finally an alternative to
- indexed tags.
- </p>
- </subsection>
- <subsection name="Indexed Tags">
- <p>
- The "indexed tags" feature is provided by several tags that have an
- optional boolean "indexed" attribute. This is only legal when inside a
- "<logic:iterate>" tag. When the "indexed" attribute is true, then
- the tag will incorporate the loop index into the resulting HTML component.
- </p>
- <p>
- The several tags that support the "indexed" attribute can be broken into
- three groups, split by what they do to incorporate the loop index into the
- resulting HTML component.
- </p>
- <table>
- <thead>
- <tr>
- <th>Group 1</th><th>Group 2</th><th>Group 3</th>
- </tr>
- </thead>
- <tr><td>checkbox</td><td>button</td><td>link</td></tr>
- <tr><td>file</td><td>image</td><td> </td></tr>
- <tr><td>hidden</td><td>submit</td><td> </td></tr>
- <tr><td>password</td><td> </td><td> </td></tr>
- <tr><td>radio</td><td> </td><td> </td></tr>
- <tr><td>select</td><td> </td><td> </td></tr>
- <tr><td>text</td><td> </td><td> </td></tr>
- <tr><td>textarea</td><td> </td><td> </td></tr>
- </table>
- <p>
- In Group 1, all of these tags will generate an HTML "name" attribute of
- "name[nn].property". The value of each tag will also be initialized by
- the getter method corresponding to that property specification.
- </p>
- <p>
- In Group 2, these tags will generate an HTML "name" attribute of
- "property[nn]". These three tags don't have "name" attributes, so since
- it wouldn't make sense to use "[nn].property" (no name value), the array
- indexes are attached to the property instead.
- </p>
- <p>
- The "link" tag in Group 3 isn't anything like any of the others. The base
- description of the "link" tag doesn't even mention how this works, but the
- description of the "indexed" tag describes how it works somewhat (although
- it doesn't specifically say that it uses the name "index" if "indexId"
- isn't set). In short, the "indexed" behavior of this tag is to add a URL
- query parameter, where the parameter name is "index" or the value of the
- "indexId" attribute, and the parameter value is the current index value.
- Outside of this, the "indexed" behavior of the "link" tag needs no more
- explanation, in contrast to the tags in the first two groups.
- </p>
- </subsection>
- <subsection name="The Wrinkle with Indexed Tags">
- <p>
- The problem with using the "indexed" attribute to automatically attach the
- loop index is that it gives you less control over how the loop index is
- used. For instance, in our earlier examples using the "<html:text>"
- tag, we attached the loop index to the end of the "property" attribute
- value, which was "labelValue" in our example. This results in a "name"
- attribute value in the HTML component of "labelValue[nn]". This maps to a
- "labelValue" indexed property on the "stringbean" bean instance.
- </p>
- <p>
- However, if we instead add the "indexed" attribute, and remove the manual
- attachment of the loop index, then the resulting "name" attribute in the
- HTML component ends up as "stringbean[nn].labelValue". This will not work
- as is. It can be changed to work, however. From the previous example
- (indexedtest5.jsp), the "<html:text>" component would change the
- "name" attribute from "stringbean" to "labelValue", and the "property"
- attribute to "label". With the "indexed" attribute, that ends up with a
- "name" attribute value of "labelValue[nn].label".
- </p>
- <p>
- So, it's very likely you could use indexed tags to support your needs for
- indexed properties, but you have to understand the resulting structure of
- your "name" attribute in order to understand what other attribute values
- you need.
- </p>
- </subsection>
- <subsection name="Using Struts-EL To Avoid Some Of The Pain">
- <p>
- The "indexed tags" feature was created partially because of the awkward
- process for encoding the loop index into the property attribute, using a
- JSP expression. The creation of the <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>
- eventually resulted in a solution that makes that process less painful.
- </p>
- <p>
- The JSTL uses a string-based expression language to evaluate attribute
- values, instead of using a run-time JSP expression. The engine that
- performs these evaluations is often called just "EL" (expression language)
- for short. After the JSTL was created, a derivative of the Struts tag
- library called Struts-EL was created. In short, this does everything that
- the Struts tag library does, but it uses the JSTL EL engine to evaluate
- attribute values.
- </p>
- <p>
- If you use Struts-EL, you can get back some of the flexibility of encoding
- your loop indices manually, but the resulting expressions will be a little
- more readable, and thus maybe a little easier to maintain.
- </p>
- <p>
- For instance, following this is a version of "indexedtest5.jsp" using
- Struts-EL:
- </p>
- <pre>
-<!-- indexedtest6.jsp -->
-<%@ taglib uri="/WEB-INF/struts-html-el.tld" prefix="html-el" %>
-<%@ taglib uri="/WEB-INF/struts-logic-el.tld" prefix="logic-el" %>
-<html>
- <body>
- <html-el:form action="indexedtest6.do">
- <logic-el:iterate name="stringbean" property="stringArray" id="foo"
- indexId="ctr">
- <html-el:text name="stringbean"
- property="labelValue[${ctr}].label" />
- </logic-el:iterate>
- <html-el:submit property="submitValue">Submit Changes</html:submit>
- </html-el:form>
- </body>
-</html></pre>
- <p>
- The Struts-EL library is part of the Struts distribution, in the "contrib"
- directory. The one drawback to using Struts-EL is that it requires a web
- container supporting the Servlet 2.3 specification.
- </p>
- </subsection>
- </section>
- </body>
+ public StringBean() {
+ map.put("zero", strAry[0]);
+ map.put("one", strAry[1]);
+ map.put("two", strAry[2]);
+ map.put("three", strAry[3]);
+ map.put("four", strAry[4]);
+ }
+
+ public Object getStringMapped(String key) {
+ return map.get(key);
+ }
+
+ public void setStringMapped(String key, Object value) {
+ map.put(key, value);
+ }
+ }</pre>
+ <p>
+ Note the "get" and "set" methods to represent the mapped
+ property.
+ </p>
+ <pre>
+ <!-- indexedtest3.jsp -->
+ <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"
+ %>
+ <jsp:useBean id="bean"
+ class="org.apache.struts.webapp.exercise.StringBean"/>
+ <bean:write name="bean" property="stringMapped(two)"/></pre>
+ <p>
+ Note the property value of "stringMapped(two)". This will
+ reference the
+ mapped property "stringMapped", using the key value of
+ "two".
+ </p>
+ <p>
+ When this page is executed, it will print just the string
+ "String 2",
+ which is the string stored in the HashMap with the key
+ "two".
+ </p>
+ </subsection>
+ <subsection name="Nested Properties">
+ <p>
+ Nested properties allows you to combine normal properties,
+ indexed
+ properties, and mapped properties in a hierarchical
+ fashion. A property
+ value of a bean does not have to be a primitive like "int"
+ or "String.
+ The property value can be a bean with its own properties.
+ The following
+ example demonstrates this.
+ </p>
+ <pre>
+ package org.apache.struts.webapp.exercise;
+ import org.apache.struts.util.LabelValueBean;
+ import org.apache.struts.action.ActionForm;
+ public class StringBean4 extends ActionForm {
+ private LabelValueBean[] lvbeans;
+
+ public StringBean() {
+ lvbeans = new LabelValueBean[5];
+ lvbeans[0] = new LabelValueBean("Zero", 0+"");
+ lvbeans[1] = new LabelValueBean("One", 1+"");
+ lvbeans[2] = new LabelValueBean("Two", 2+"");
+ lvbeans[3] = new LabelValueBean("Three", 3+"");
+ lvbeans[4] = new LabelValueBean("Four", 4+"");
+ }
+
+ public LabelValueBean getLabelValue(int index) {
+ return lvbeans[index];
+ }
+ }</pre>
+ <p>
+ First note the use of the class "LabelValueBean". This is
+ a simple class
+ provided in the Struts library which represents a pair of
+ two Strings, a
+ "label" and a "value". It itself is a bean, providing
+ these two
+ properties with standard getters and setter methods.
+ </p>
+ <p>
+ Then, see the "getLabelValue()" method, representing the
+ indexed property
+ "labelValue". This class doesn't show a "setter" method.
+ If you only ever
+ provide read-only access a property, then it is not
+ necessary to provide a
+ setter method.
+ </p>
+ <pre>
+ <!-- indexedtest4.jsp -->
+ <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"
+ %>
+ <jsp:useBean id="bean"
+ class="org.apache.struts.webapp.exercise.StringBean"/>
+ <bean:write name="bean" property="labelValue[1].label"/></pre>
+ <p>
+ Note here the "nested" property reference. It is first
+ using the indexed
+ property "labelValue" and then the "normal" property of
+ the LabelValueBean
+ to get the final result. When this page is executed, it
+ will print the
+ string "One", representing the "label" property of the 1st
+ entry of the
+ array represented by the "labelValue" indexed property.
+ </p>
+ </subsection>
+ <subsection name="Dynamic Indexes for Indexed Properties">
+ <p>
+ When people started using indexed properties in Struts
+ tags, I'm
+ reasonably certain they started out with a high level of
+ enthusiasm, but
+ were somewhat frustrated when they discovered reality. The
+ reality is
+ that the "index" for indexed properties often needs to be
+ a dynamic value,
+ usually from the "indexId" counter in the "<logic:iterate>"
+ tag.
+ </p>
+ <p>
+ For instance, the following example JSP page using the
+ same "StringBean"
+ bean class uses a dynamic value for the index:
+ </p>
+ <pre>
+ <!-- indexedtest5.jsp -->
+ <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"
+ %>
+ <%@ taglib uri="/WEB-INF/struts-logic.tld"
+ prefix="logic" %>
+ <html>
+ <body>
+ <html:form action="indexedtest5.do">
+ <logic:iterate name="stringbean" property="stringArray"
+ id="foo"
+ indexId="ctr">
+ <html:text name="stringbean"
+ property='<%= "labelValue[" + ctr + "].label" %>' />
+ </logic:iterate>
+ <html:submit property="submitValue">Submit Changes</html:submit>
+ </html:form>
+ </body>
+ </html></pre>
+ <p>
+ The JSP expression syntax for the
+ <code>property</code>
+ attribute is somewhat
+ messy and easy to get wrong so it's something we want to
+ avoid. One
+ way to make this a little cleaner is to use "indexed
+ tags", but there's a
+ wrinkle to this approach. We'll first cover the details of
+ indexed tags,
+ then we'll talk about the wrinkle, and then finally an
+ alternative to
+ indexed tags.
+ </p>
+ </subsection>
+ <subsection name="Indexed Tags">
+ <p>
+ The "indexed tags" feature is provided by several tags
+ that have an
+ optional boolean "indexed" attribute. This is only legal
+ when inside a
+ "<logic:iterate>" tag. When the "indexed" attribute
+ is true, then
+ the tag will incorporate the loop index into the resulting
+ HTML component.
+ </p>
+ <p>
+ The several tags that support the "indexed" attribute can
+ be broken into
+ three groups, split by what they do to incorporate the
+ loop index into the
+ resulting HTML component.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th>Group 1</th>
+ <th>Group 2</th>
+ <th>Group 3</th>
+ </tr>
+ </thead>
+ <tr>
+ <td>checkbox</td>
+ <td>button</td>
+ <td>link</td>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>image</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>hidden</td>
+ <td>submit</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>radio</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>select</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>text</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>textarea</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ </table>
+ <p>
+ In Group 1, all of these tags will generate an HTML "name"
+ attribute of
+ "name[nn].property". The value of each tag will also be
+ initialized by
+ the getter method corresponding to that property
+ specification.
+ </p>
+ <p>
+ In Group 2, these tags will generate an HTML "name"
+ attribute of
+ "property[nn]". These three tags don't have "name"
+ attributes, so since
+ it wouldn't make sense to use "[nn].property" (no name
+ value), the array
+ indexes are attached to the property instead.
+ </p>
+ <p>
+ The "link" tag in Group 3 isn't anything like any of the
+ others. The base
+ description of the "link" tag doesn't even mention how
+ this works, but the
+ description of the "indexed" tag describes how it works
+ somewhat (although
+ it doesn't specifically say that it uses the name "index"
+ if "indexId"
+ isn't set). In short, the "indexed" behavior of this tag
+ is to add a URL
+ query parameter, where the parameter name is "index" or
+ the value of the
+ "indexId" attribute, and the parameter value is the
+ current index value.
+ Outside of this, the "indexed" behavior of the "link" tag
+ needs no more
+ explanation, in contrast to the tags in the first two
+ groups.
+ </p>
+ </subsection>
+ <subsection name="The Wrinkle with Indexed Tags">
+ <p>
+ The problem with using the "indexed" attribute to
+ automatically attach the
+ loop index is that it gives you less control over how the
+ loop index is
+ used. For instance, in our earlier examples using the "<html:text>"
+ tag, we attached the loop index to the end of the
+ "property" attribute
+ value, which was "labelValue" in our example. This results
+ in a "name"
+ attribute value in the HTML component of "labelValue[nn]".
+ This maps to a
+ "labelValue" indexed property on the "stringbean" bean
+ instance.
+ </p>
+ <p>
+ However, if we instead add the "indexed" attribute, and
+ remove the manual
+ attachment of the loop index, then the resulting "name"
+ attribute in the
+ HTML component ends up as "stringbean[nn].labelValue".
+ This will not work
+ as is. It can be changed to work, however. From the
+ previous example
+ (indexedtest5.jsp), the "<html:text>" component
+ would change the
+ "name" attribute from "stringbean" to "labelValue", and
+ the "property"
+ attribute to "label". With the "indexed" attribute, that
+ ends up with a
+ "name" attribute value of "labelValue[nn].label".
+ </p>
+ <p>
+ So, it's very likely you could use indexed tags to support
+ your needs for
+ indexed properties, but you have to understand the
+ resulting structure of
+ your "name" attribute in order to understand what other
+ attribute values
+ you need.
+ </p>
+ </subsection>
+ <subsection name="Using Struts-EL To Avoid Some Of The Pain">
+ <p>
+ The "indexed tags" feature was created partially because
+ of the awkward
+ process for encoding the loop index into the property
+ attribute, using a
+ JSP expression. The creation of the
+ <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>
+ eventually resulted in a solution that makes that process
+ less painful.
+ </p>
+ <p>
+ The JSTL uses a string-based expression language to
+ evaluate attribute
+ values, instead of using a run-time JSP expression. The
+ engine that
+ performs these evaluations is often called just "EL"
+ (expression language)
+ for short. After the JSTL was created, a derivative of the
+ Struts tag
+ library called Struts-EL was created. In short, this does
+ everything that
+ the Struts tag library does, but it uses the JSTL EL
+ engine to evaluate
+ attribute values.
+ </p>
+ <p>
+ If you use Struts-EL, you can get back some of the
+ flexibility of encoding
+ your loop indices manually, but the resulting expressions
+ will be a little
+ more readable, and thus maybe a little easier to maintain.
+ </p>
+ <p>
+ For instance, following this is a version of
+ "indexedtest5.jsp" using
+ Struts-EL:
+ </p>
+ <pre>
+ <!-- indexedtest6.jsp -->
+ <%@ taglib uri="/WEB-INF/struts-html-el.tld"
+ prefix="html-el" %>
+ <%@ taglib uri="/WEB-INF/struts-logic-el.tld"
+ prefix="logic-el" %>
+ <html>
+ <body>
+ <html-el:form action="indexedtest6.do">
+ <logic-el:iterate name="stringbean"
+ property="stringArray" id="foo"
+ indexId="ctr">
+ <html-el:text name="stringbean"
+ property="labelValue[${ctr}].label" />
+ </logic-el:iterate>
+ <html-el:submit property="submitValue">Submit
+ Changes</html:submit>
+ </html-el:form>
+ </body>
+ </html></pre>
+ <p>
+ The Struts-EL library is part of the Struts distribution,
+ in the "contrib"
+ directory. The one drawback to using Struts-EL is that it
+ requires a web
+ container supporting the Servlet 2.3 specification.
+ </p>
+ </subsection>
+ </section>
+ </body>
</document>
Modified: struts/taglib/trunk/xdocs/navigation.xml
URL: http://svn.apache.org/viewcvs/struts/taglib/trunk/xdocs/navigation.xml?rev=376854&r1=376853&r2=376854&view=diff
==============================================================================
--- struts/taglib/trunk/xdocs/navigation.xml (original)
+++ struts/taglib/trunk/xdocs/navigation.xml Fri Feb 10 13:09:57 2006
@@ -1,46 +1,47 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="Struts JSP Taglib">
-<title>Apache Struts - Struts JSP Taglib</title>
+ <title>Apache Struts - Struts JSP Taglib</title>
<body>
<menu name="Struts JSP Taglib Guides">
- <item name="Bean" href="dev_bean.html"/>
+ <item name="Bean" href="dev_bean.html"/>
<item name="HTML" href="dev_html.html"/>
<item name="Logic" href="dev_logic.html"/>
<item name="Nested" href="dev_nested.html"/>
</menu>
<menu name="FAQs and HOWTOs">
- <item name="Taglib FAQ" href="faq.html"/>
- <item name="Building View Components" href="building_view.html"/>
- <item name="Indexed Properties" href="indexedprops.html"/>
- <item name="Secure Socket Layer and Web Applications " href="ssl.html"/>
+ <item name="Taglib FAQ" href="faq.html"/>
+ <item name="Building View Components" href="building_view.html"/>
+ <item name="Indexed Properties" href="indexedprops.html"/>
+ <item name="Secure Socket Layer and Web Applications "
+ href="ssl.html"/>
<item name="Struts Validator" href="dev_validator.html"/>
</menu>
<menu name="Quick Links">
- <item name="Display Tag"
- href="http://displaytag.sourceforge.net/"/>
+ <item name="Display Tag"
+ href="http://displaytag.sourceforge.net/"/>
<item name="<html2>"
- href="http://www.rabago.net/struts/html2/"/>
+ href="http://www.rabago.net/struts/html2/"/>
<item name="JSTL"
href="http://java.sun.com/products/jsp/jstl/"/>
-
+
<item name="JSF"
href="http://java.sun.com/j2ee/javaserverfaces/"/>
-
+
<item name="Struts Faces"
href="../struts-faces/index.html"/>
- <item name="Struts Layout"
- href="http://struts.application-servers.com"/>
+ <item name="Struts Layout"
+ href="http://struts.application-servers.com"/>
- <item name="Struts Menu"
- href="http://struts-menu.sourceforge.net/"/>
+ <item name="Struts Menu"
+ href="http://struts-menu.sourceforge.net/"/>
<item name="Struts Shale"
href="../shale/index.html"/>
-
+
<item name="Apache Struts Home"
href="../index.html"/>
</menu>
Modified: struts/taglib/trunk/xdocs/ssl.xml
URL: http://svn.apache.org/viewcvs/struts/taglib/trunk/xdocs/ssl.xml?rev=376854&r1=376853&r2=376854&view=diff
==============================================================================
--- struts/taglib/trunk/xdocs/ssl.xml (original)
+++ struts/taglib/trunk/xdocs/ssl.xml Fri Feb 10 13:09:57 2006
@@ -18,140 +18,203 @@
-->
<document>
-<properties>
- <title>Secure Socket Layer and Web Applications </title>
-</properties>
-
-<body>
-
-<section href="ssl" name="Secure Socket Layer and Web Applications">
-
-<a name="overview"/>
-<subsection name="Overview">
-
-<p>
-Many web applications, especially those deployed for e-commerce, necessitate the
-transmission of sensitive data between the web server and the client browser. This data
-may include passwords, credit card numbers, bank account numbers or any other
-information that users would not want to divulge to the general public. To protect
-sensitive data during transmission, application developers typically use the Secure
-Sockets Layer (SSL) and its companion protocol, HTTP over Secure Sockets Layer
-(HTTPS). HTTPS employs SSL to protect data by encrypting it at the source, be it the
-server or the client, and decrypting it at the destination. This prevents anyone monitoring
-Internet data transmissions from easily capturing this data. The client and server
-exchange public keys to enable encryption and decryption to occur.
-</p>
-
-<p>
-The encryption/decryption process comes at a performance price, however. The
-throughput of data for a web server transmitting via HTTPS is often as little as one-tenth
-that of data transmission via HTTP. For this reason, it is undesirable to deploy an entire
-web application under SSL. For fastest performance, it is best to deploy a web
-application under HTTP and employ HTTPS only for those pages and processes that
-transmit sensitive data.
-</p>
-
-</subsection>
-
-<a name="mixing"/>
-<subsection name="Mixing Protocols in Web Applications">
-
-<p>
-Switching back and forth between the two protocols can require hard-coding the protocol
-and full URL in every link to each resource in the web application. This creates an
-ongoing maintenance headache for developers each time a server name changes or secure
-protocol requirements change for resources in the web app.
-</p>
-
-<p>
-Another significant hazard is that there is nothing to prevent a user from specifying the
-wrong protocol by manually entering a URL into the browser. The penalty for manually
-specifying HTTPS for a page or servlet that does not require HTTPS is reduced
-performance. Far worse is the penalty for manually specifying HTTP for non-secure
-access of a page that does require HTTPS: public exposure of sensitive data.
-</p>
-
-</subsection>
-
-<a name="help"/>
-<subsection name="Help from Deployment Descriptor">
-
-<p>
-To help overcome the problem of non-secure access of sensitive data, the Java Servlet
-Specification (versions 2.2 and 2.3) defines the transport-guarantee element of the
-web.xml deployment descriptor file. The transport-guarantee element must specify one
-of three types of protection for communication between client and server: NONE,
-INTEGRAL, or CONFIDENTIAL. For most containers a specification of INTEGRAL
-or CONFIDENTIAL is treated as a requirement for SSL usage. Web application
-containers will prevent users from accessing web resources over HTTP if they have been
-so specified.
-</p>
-
-<p>
-The implementation for blocking HTTP access to web resources specified as INTEGRAL
-or CONFIDENTIAL varies from container to container. If a user attempts to access such
-a resource over HTTP, some containers will present that user with an error message
-instructing them to use the HTTPS protocol for accessing the requested resource. Other
-containers will actually redirect the request using the HTTPS protocol, but then continue
-using the HTTPS protocol for all subsequent requests, even those for resources with a
-transport-guarantee specification of NONE.
-</p>
-
-</subsection>
-
-<a name="sslext"/>
-<subsection name="The sslext Struts Extension">
-
-<p>
-An extension to Struts 1.1, named sslext, helps solve many of these issues for Struts
-developers. It extends the ActionConfig class, RequestProcessor, and Plugin classes to
-define a framework where developers may specify the transmission protocol behavior for
-Struts applications. Within the Struts configuration file, developers specify which action
-requests require HTTPS transmission and which should use HTTP. Developers can also
-specify whether to redirect "improperly-protocoled" requests to the correct protocol.
-</p>
-
-<p>
-In addition to these extensions, the <html:link> and the <html:form> tags have been
-extended. In these extensions, the Struts actions specified in either of these tags are
-analyzed to determine the protocol that should be used in requesting that action. The
-HTML generated by these tags will specify the proper protocol. An additional custom
-tag is defined for allowing users to specify the transmission protocol for an individual
-JSP. This is most often used for form-based authentication pages.
-</p>
-
-<p>
-The sslext library may be obtained from <a href="http://sslext.sourceforge.net">
-http://sslext.sourceforge.net</a>
-</p>
-
-</subsection>
-
-<a name="legacy"/>
-<subsection name="Legacy Browser Issue">
-
-<p>
-One additional complication faced by developers of web applications is that some
-browsers (e.g. pre-6.0 versions of Netscape Navigator) will treat requests to different
-protocols and ports on the same server as requests to different domains. This causes
-these browsers to initiate a new session each time a different protocol or port is specified
-in a request. This problem can only be solved at the container level. Some containers
-have a "session domain" or "cookie domain" configuration parameter to allow the session
-to be shared across different servers in the same domain. As an example, the Weblogic
-Server has a "CookieDomain" property configured in its weblogic.xml deployment
-descriptor. Thankfully, the effects of this problem are diminishing as people upgrade
-their browsers to the current versions.
-</p>
-
-</subsection>
-
-<a name="containers"/>
-<subsection name="Configuring Containers for SSL">
-<p>
-The procedure for configuring SSL for a container will be specific to that container. The
-procedure for enabling SSL for Tomcat can be found
-<a href="http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html">here</a>.
-</p>
-</subsection>
-
-</section></body></document>
+ <properties>
+ <title>Secure Socket Layer and Web Applications</title>
+ </properties>
+
+ <body>
+
+ <section href="ssl" name="Secure Socket Layer and Web Applications">
+
+ <a name="overview"/>
+ <subsection name="Overview">
+
+ <p>
+ Many web applications, especially those deployed for
+ e-commerce, necessitate the
+ transmission of sensitive data between the web server and
+ the client browser. This data
+ may include passwords, credit card numbers, bank account
+ numbers or any other
+ information that users would not want to divulge to the
+ general public. To protect
+ sensitive data during transmission, application developers
+ typically use the Secure
+ Sockets Layer (SSL) and its companion protocol, HTTP over
+ Secure Sockets Layer
+ (HTTPS). HTTPS employs SSL to protect data by encrypting
+ it at the source, be it the
+ server or the client, and decrypting it at the
+ destination. This prevents anyone monitoring
+ Internet data transmissions from easily capturing this
+ data. The client and server
+ exchange public keys to enable encryption and decryption
+ to occur.
+ </p>
+
+ <p>
+ The encryption/decryption process comes at a performance
+ price, however. The
+ throughput of data for a web server transmitting via HTTPS
+ is often as little as one-tenth
+ that of data transmission via HTTP. For this reason, it is
+ undesirable to deploy an entire
+ web application under SSL. For fastest performance, it is
+ best to deploy a web
+ application under HTTP and employ HTTPS only for those
+ pages and processes that
+ transmit sensitive data.
+ </p>
+
+ </subsection>
+
+ <a name="mixing"/>
+ <subsection name="Mixing Protocols in Web Applications">
+
+ <p>
+ Switching back and forth between the two protocols can
+ require hard-coding the protocol
+ and full URL in every link to each resource in the web
+ application. This creates an
+ ongoing maintenance headache for developers each time a
+ server name changes or secure
+ protocol requirements change for resources in the web app.
+ </p>
+
+ <p>
+ Another significant hazard is that there is nothing to
+ prevent a user from specifying the
+ wrong protocol by manually entering a URL into the
+ browser. The penalty for manually
+ specifying HTTPS for a page or servlet that does not
+ require HTTPS is reduced
+ performance. Far worse is the penalty for manually
+ specifying HTTP for non-secure
+ access of a page that does require HTTPS: public exposure
+ of sensitive data.
+ </p>
+
+ </subsection>
+
+ <a name="help"/>
+ <subsection name="Help from Deployment Descriptor">
+
+ <p>
+ To help overcome the problem of non-secure access of
+ sensitive data, the Java Servlet
+ Specification (versions 2.2 and 2.3) defines the
+ transport-guarantee element of the
+ web.xml deployment descriptor file. The
+ transport-guarantee element must specify one
+ of three types of protection for communication between
+ client and server: NONE,
+ INTEGRAL, or CONFIDENTIAL. For most containers a
+ specification of INTEGRAL
+ or CONFIDENTIAL is treated as a requirement for SSL usage.
+ Web application
+ containers will prevent users from accessing web resources
+ over HTTP if they have been
+ so specified.
+ </p>
+
+ <p>
+ The implementation for blocking HTTP access to web
+ resources specified as INTEGRAL
+ or CONFIDENTIAL varies from container to container. If a
+ user attempts to access such
+ a resource over HTTP, some containers will present that
+ user with an error message
+ instructing them to use the HTTPS protocol for accessing
+ the requested resource. Other
+ containers will actually redirect the request using the
+ HTTPS protocol, but then continue
+ using the HTTPS protocol for all subsequent requests, even
+ those for resources with a
+ transport-guarantee specification of NONE.
+ </p>
+
+ </subsection>
+
+ <a name="sslext"/>
+ <subsection name="The sslext Struts Extension">
+
+ <p>
+ An extension to Struts 1.1, named sslext, helps solve many
+ of these issues for Struts
+ developers. It extends the ActionConfig class,
+ RequestProcessor, and Plugin classes to
+ define a framework where developers may specify the
+ transmission protocol behavior for
+ Struts applications. Within the Struts configuration file,
+ developers specify which action
+ requests require HTTPS transmission and which should use
+ HTTP. Developers can also
+ specify whether to redirect "improperly-protocoled"
+ requests to the correct protocol.
+ </p>
+
+ <p>
+ In addition to these extensions, the <html:link> and
+ the <html:form> tags have been
+ extended. In these extensions, the Struts actions
+ specified in either of these tags are
+ analyzed to determine the protocol that should be used in
+ requesting that action. The
+ HTML generated by these tags will specify the proper
+ protocol. An additional custom
+ tag is defined for allowing users to specify the
+ transmission protocol for an individual
+ JSP. This is most often used for form-based authentication
+ pages.
+ </p>
+
+ <p>
+ The sslext library may be obtained from
+ <a href="http://sslext.sourceforge.net">
+ http://sslext.sourceforge.net</a>
+ </p>
+
+ </subsection>
+
+ <a name="legacy"/>
+ <subsection name="Legacy Browser Issue">
+
+ <p>
+ One additional complication faced by developers of web
+ applications is that some
+ browsers (e.g. pre-6.0 versions of Netscape Navigator)
+ will treat requests to different
+ protocols and ports on the same server as requests to
+ different domains. This causes
+ these browsers to initiate a new session each time a
+ different protocol or port is specified
+ in a request. This problem can only be solved at the
+ container level. Some containers
+ have a "session domain" or "cookie domain" configuration
+ parameter to allow the session
+ to be shared across different servers in the same domain.
+ As an example, the Weblogic
+ Server has a "CookieDomain" property configured in its
+ weblogic.xml deployment
+ descriptor. Thankfully, the effects of this problem are
+ diminishing as people upgrade
+ their browsers to the current versions.
+ </p>
+
+ </subsection>
+
+ <a name="containers"/>
+ <subsection name="Configuring Containers for SSL">
+ <p>
+ The procedure for configuring SSL for a container will be
+ specific to that container. The
+ procedure for enabling SSL for Tomcat can be found
+ <a href="http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html">
+ here</a>
+ .
+ </p>
+ </subsection>
+
+ </section>
+ </body>
+</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org