Struts秘籍之第2段:第3.4式:在表单中使用索引属性

 

第3.4式. 在表单中使用索引属性

问题

你想要在表单中创建对应于一个Bean中的索引属性的一套输入字段。

动作要领

在Struts html标签库的标签中使用indexed属性来产生属性值:

 

< html:form  action ="TestOneAction" >< p >
  
< logic:iterate  name ="MyForm"  property ="stringArray"  
                   id
="stringValue"  indexId ="ctr" >
    
< br />
    
< html:text  property ="stringArray"  indexed ="true" />
</ logic:iterate >
</ html:form >

 

动作变化

如第3.3时所示,访问索引值以供显示是很容易的。但是,在表单中使用索引属性则有些麻烦。如果所产生的输入字段的名称没有正确的格式化,在HTML表单被提交后, Apache Struts Web Framework 便不能正确的装配ActionForm。Struts 要使用Jakarta Commons BeanUtils 包来从HTTP请求中的值组装ActionForm。特别地,BeanUtils.populate( )方法是从表单提交时从HTTP请求数据发送的数据中装载ActionForm的。

对于索引值,BeanUtils.populate( )使用请求参数来决定适当的setter 方法以调用ActionForm。表3-3 列出了不同的表单输入字段是如何处理的。表中列出了HTML 标签,对应的HTTP 请求响应对,以及在请求被处理时在ActionForm之上调用的方法。

表3-3. ActionForm 组装示例

HTML form 输入标记

产生的请求对

导致的方法调用

<input type="text" name="bar">

bar=someValue

Form.setBar("someValue")

<input type="text" name="sna.fug">

sna.fug=blah

Form.getSna( ).setFug("blah");

<input type="text" name="baz[0]">

baz[0]=someValue

Form.setBaz(0,"firstVal");

<input type="text" name="glub[1].waf">

glub[1].waf=halb

Form.getGlub(1).setWaf("halb");

<input type="text" name="dog.leg[2]">

dog.leg[2]=lame

Form.getDog( ).setLeg(2, "lame");

 

考虑一个允许用户输入最喜爱列表,比如颜色和网站,的表单。持有这些数据的ActionForm包含一个表示用户名称的String属性,表示用户喜好颜色的String数组,以及一个表示用户喜好网站的WebLink对象的List。WebLink类如Example 3-5所示,它定义了一个简单的JavaBean,具有表示站点名称和URL的属性。

Example 3-5. WebLink JavaBean

 

package com.oreilly.strutsckbk;

public   class  WebLink  {
    
public String getName( ) {
        
return name;
    }

    
public void setName(String name) {
        
this.name = name;
    }

    
public String getUrl( ) {
        
return url;
    }

    
public void setUrl(String url) {
        
this.url = url;
    }

    
private String url;
    
private String name;
}

 

form bean, FavoritesForm, 则包含了用户名称,喜爱颜色,以及喜好网站。如Example 3-6所示:

Example 3-6. FavoritesForm form bean

 

package com.oreilly.strutsckbk;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts.action.ActionForm;

public  final  class  FavoritesForm extends ActionForm   {
    
public FavoritesForm( ) {
        webLinks 
= new ArrayList( );
        
for (int i=0; i<5; i++) webLinks.add(new WebLink( )); 
        colors 
= new String[3];
    }
    
    
public String getName( ) {
        
return name;
    }

    
public void setName(String name) {
        
this.name = name;
    }

    
public String getColor(int index) {
        
return colors[index];
    }

    
public void setColor(int index, String color) {
        colors[index] 
= color;
    }

    
public String[] getColor( ) {
        
return colors;
    }

    
public List getWebLinks( ) {
        
return webLinks;
    }

    
public WebLink getWebLink(int index) {
        
return (WebLink)webLinks.get(index);
    }

    
public void setWebLink(int index, WebLink webLink) {
        webLinks.
set(index, webLink);
    }

    
    
public void reset( ) {
        webLinks.clear( );
        colors 
= new String[3];
    }

    
    
private List webLinks;
    
private String name;        
    
private String[] colors;    
}

 

现在你可以创建一个JSP 页面 (favorites.jsp) ,通过它用户可以输入表单中的相应数据,其代码如Example 3-7所示.

Example 3-7. FavoritesForm JSP

 

< %@ page  contentType ="text/html;charset=UTF-8"  language ="java"  % >
< %@ taglib  uri ="/WEB-INF/struts-bean.tld"  prefix ="bean"  % >
< %@ taglib  uri ="/WEB-INF/struts-html.tld"  prefix ="html"  % >
< %@ taglib  uri ="/WEB-INF/struts-logic.tld"  prefix ="logic"  % >
< %@ taglib  uri ="http://java.sun.com/jstl/core"  prefix ="c"  % >

< html:html  locale ="true" >
< head >
< title >< bean:message  key ="index.title" /></ title >
< html:base />
</ head >
< body  bgcolor ="white" >
< h2 > Favorites Poll </ h2 >
< html:form  action ="/admin/ViewFavorites" >
    
< p >
        What is your name:
        
< br />< html:text  property ="name" />
    
</ p >
    
< p >
        What are your three favorite colors:
        
< br />< html:text  property ="color[0]" />
        
< br />< html:text  property ="color[1]" />
        
< br />< html:text  property ="color[2]" />
    
</ p >
   
< p >
      What are your favorite links?
      
< table >
         
< tr >
            
< th > Name </ th >
            
< th > URL </ th >
         
</ tr >
         
< tr >
            
< td >< html:text  property ="webLink[0].name" /></ td >
            
< td >< html:text  property ="webLink[0].url" /></ td >
         
</ tr >
      
</ table >
   
</ p >
    
< html:submit />
    
< html:reset />
</ html:form >
</ body >
</ html:html >

 

因为Example 3-7 中的索引值是硬编码,不是动态的,html:text标签的property值便很容易构造,所以产生的HTML 标签便具有适当的name属性值。然而,假设你想要使用logic:iterate标签来产生重复的输入字段。比如,为了对color属性这样做,你可能想要尝试以下的JSP 代码:

 

What are your three favorite colors:
  
< logic:iterate  name ="FavoritesForm"  id ="theColor" >
    
< br />< html:text  property ="color"  indexed ="true" />
  
</ logic:iterate >

 

但是这段代码不会产生需要的HTML 标记。indexed属性对为特定的Struts html标签(这里是html:text)的name属性所指定的值应用一个索引(即, [n]) 。如果你使用上面的片断部署了一个JSP ,所产生的HTML可能是下面的样子:

 

What are your three favorite colors:
< br />< input  type ="text"  name ="org.apache.struts.taglib.html.
BEAN[0].color"
 value ="[Ljava.lang.String;@5f1ba8" >
< br />< input  type ="text"  name ="org.apache.struts.taglib.html.
BEAN[1].color"
 value ="[Ljava.lang.String;@5f1ba8" >
< br />< input  type ="text"  name ="org.apache.struts.taglib.html.
BEAN[2].color"
 value ="[Ljava.lang.String;@5f1ba8" >

 

索引并没有应用到属性的值。相反,却被应用到了Form Bean的内部internal Apache Struts Web Framework 名称。另外,value包含了对数组调用toString( )方法的结果,而不是数组中特定的元素。.

说到底,意思就是当你需要设置一个本身是复杂对象,比如一个JavaBean 的索引属性的嵌套的简单属性时,indexed属性时很有用的。你可以在logic:iterate标签中为一个非嵌套属性产生输入字段,但是你却必须借助scriptlet 来产生数组索引:

 

What are your three favorite colors:
  
< logic:iterate  name ="FavoritesForm"  id ="theColor"  indexId ="ctr" >
    
< br />< html:text  property ='<%="color["+ctr+"]"%>'/>
  
</logic:iterate >

 

假设你想要使用logic:iterate标签来为喜好链接(WebLink对象)产生输入字段。这种情况下,indexed的行为则正如你愿:

 

What are your favorite links?
< table >
  
< tr >
     
< th > Name </ th >
     
< th > URL </ th >
  
</ tr >
  
< logic:iterate  id ="webLink"  name ="FavoritesForm"  property ="webLinks" >
    
< tr >
      
< td >< html:text  name ="webLink"  property ="name"  indexed ="true" /></ td >
      
< td >< html:text  name ="webLink"  property ="url"  indexed ="true" /></ td >
    
</ tr >
  
</ logic:iterate >
< table >

 

在html标签中使用indexed属性多少有点使人混淆。混淆之处主要来自于name属性的不同意义。大多数情况下,在使用html标签时,name都可以忽略因为值将基于action mapping 中声明的form-bean。然而,在使用indexed属性时,name却引用到对应的ActionForm的嵌套的索引属性。

我们回去看color属性的问题,你可以选择使用scriptlet之外的方式。可以使用Struts html-el标签或者JSTL。它们都可以做一些和scriptlet相同的基本事情,但是它们是通过EL 表达式来进行的。最简洁的方法是使用html-el标签:

 

What are your three favorite colors:
  
< logic:iterate  name ="FavoritesForm"  id ="theColor"  indexId ="ctr" >
    
< br />< html-el:text  property ='color[${ctr}]>'/>
  
</logic:iterate >

 

如你喜欢JSTL,你也可以直接产生需要的输入标签而不是使用Struts html标签:

 

What are your three favorite colors:
< logic:iterate  id ="color"  name ="FavoritesForm"  property ="color"  indexId ="ctr" >  
  
< br />< input  type ="text"  name ="color[<c:out value='${ctr}'/>]"
             
value
="<c:out value='${FavoritesForm.color[ctr]}'/>" />

</ logic:iterate >

 

这个JSTL 版本几乎和原来使用scriptlet的版本一样丑陋。另外,因为Struts html:text和html-el:text标签都没使用, HTML input标签的value属性必须是显式编码的。如果你使用Struts html:text标签,这个值就是自动设置的。

相关招式

第3.3式讨论了在表单之外显示索引属性所用的技术。

第3.5式讨论如何在JSTL c:forEach循环中使用索引属性。

Jakarta Commons项目的BeanUtils包定义了索引属性如何解析。相关信息可访问:http://jakarta.apache.org/commons/beanutils/api/org/apache/commons/beanutils/package-summary.html#package_description.

[引用提示]阿泠引用了该文章, 地址: http://blog.donews.com/inclear/archive/2005/11/12/624363.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值