`

actionForm list

阅读更多

转载自:隔叶黄鹂

WEB 应用中一般都会处理主从表的信息, 或者称之为头层与行层的一对多的关系数据,如订单头/订单明细. 对于这种关系数据提交到后台的 Struts 的 ActionForm 的话, 这个 ActionForm 就要好好的设计一下, 不然会给自已带来许多额外的代码. 比如有的人的处理方法就是把页面提交到后台的毫无关系的散装数据非常吃力的拼凑一对多的关系对象出来.

下面举一个如今非常现实的关于股票的例子, 简单的应用场景是: 记录某个帐户所持有的股票信息,提交到后台,然后显示出来. 输入页面如下图

帐户信息包括帐户名和资金帐号;持有股票的每一行信息包括股票代码, 股票名称, 成本价, 股票数量. 股票行可以动态增删.



 
输入页面 input.jsp



 
后台处理类图


为 了简化不必要的代码, 我们要实现的终及目标是: 在输入页面上点击 "保存数据" 按钮, 由 Struts 的 RequestProcessor.processPopulate() 方法把页面提交的基本信息组装到 AccountStockForm 的 account 的对应属性中,股票行信息对应生成一个 Stock 实例加到 AccountStockForm的 List 属性 stocks 中, 后续在 AccountStockAction 中直接处理account和stocks属性就非常简单了. AccountStockForm在这里只作为一个壳.

下面从前台到后台说明关键性的代码, 完整的 MyEclipse 工程包可以点击 TestStruts135.zip 下载到.

: struts-config.xml 配置

 
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. <!DOCTYPE struts-config PUBLIC  
  3.           "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"  
  4.           "http://struts.apache.org/dtds/struts-config_1_3.dtd">   
  5. < struts-config >   
  6.     < form-beans >   
  7.         < form-bean   name = "accountStockForm"   
  8.           type = "com.unmi.form.AccountStockForm" />   
  9.     </ form-beans >   
  10.     < action-mappings >   
  11.         < action   path = "/showStock"   name = "accountStockForm"   
  12.          type = "com.unmi.action.AccountStockAction"   scope = "request" >   
  13.             < forward   name = "show"   path = "/show.jsp" />   
  14.         </ action >   
  15.     </ action-mappings >   
  16. </ struts-config >   



: 输入页面 input.jsp , 注意表单域命名

 
  1. < html:form   action = "/showStock" >   
  2.     < h3 > 记录持有的股票 < br > </ h3 >   
  3.     < fieldset > s < legend > 基本信息 </ legend >   
  4.     < table   width = "100%"   border = 0 > < tr >   
  5.         < td > 帐户名: < html:text   property = "account.name" /> </ td >   
  6.         < td > 资金帐号: < html:text   property = "account.number" /> </ td >   
  7.     </ tr > </ table >   
  8.     </ fieldset >   
  9.     < br >   
  10.     < fieldset > < legend > 持有股票 </ legend >   
  11.     < table   width = 100 border = 0   id = "stockTable" >   
  12.     < tr >   
  13.         < td > < input   type = "checkbox"   onclick = "checkAll(this)" > </ td >   
  14.         < td > 股票代码 </ td >   
  15.         < td > 股票名称 </ td >   
  16.         < td > 成本价 </ td >   
  17.         < td > 股票数量 </ td >   
  18.     </ tr >   
  19.     < tr >   
  20.         < td > < input   type = "checkbox"   name = "check" > </ td >   
  21.         < td > < input   name = "stocks[0].code"   size = "15" > </ td >   
  22.         < td > < input   name = "stocks[0].name"   size = "15" > </ td >   
  23.         < td > < input   name = "stocks[0].price"   size = "15" > </ td >   
  24.         < td > < input   name = "stocks[0].quantity"   size = "15" > </ td >   
  25.     </ tr >   
  26.     </ table >   
  27. </ html:form >   



例如输入框名 account.name 提交后能设置到 accountStockForm 的account的name属性
输入框名为 stocks[0].code 提交后会设置到 accountStockForm 的 List stocks的第一个元素的code属性.以此类推
在提交表单前要重排行层的索引,从 0 起, 否则到后右的 Form 会一些空数据.

三: AccountStockForm 的关键代码

 
  1. private  Account account =  new  Account();  
  2. private  List stocks =  new  AutoArrayList(Stock. class );  
  3.   
  4. public   void  setStocks(List stocks)  
  5. {  
  6.     this .stocks.clear();  
  7.     this .stocks.addAll(stocks);  
  8. }  



定 义了两个属性,分别是一个bean(Account,接受基本信息)和一个List(stocks,接受股票行信息),注意这两个属性必须初始化,不然在 表单提交后会出现空指针错误. setStocks方法是让stocks属性永远保有持是一个 AutoArrayList 实例. 这样在表单提交后设置值是总能调用 AutoArrayList 的 get(int index) 方法.

: 自定义的 AutoArrayList

 
  1. public   class  AutoArrayList  extends  ArrayList {  
  2.       
  3.     private  Class itemClass;  
  4.       
  5.     public  AutoArrayList(Class itemClass) {  
  6.         this .itemClass = itemClass;  
  7.     }  
  8.       
  9.     public  Object get( int  index) {  
  10.         try  {  
  11.             while  (index >= size()) {  
  12.                 add(itemClass.newInstance());  
  13.             }  
  14.         } catch  (Exception e) {  
  15.             e.printStackTrace();  
  16.         }  
  17.         return   super .get(index);  
  18.     }  
  19. }  


理 解为什么要继承一个ArrayList, 覆写get(int index)方法要简单了解 Struts 处理提交数据的工作原理: 大致如下: 页面提交后, 由 ActionServlet交给RequestProcessor的processPopulate()方法,由processPopulate()方法 收集请求数据,放在map中,key为表单域的name属性,如 name, account.name, stocks[0].code. 然后借助于 Common-beanutils 工具包设置到 ActionForm 的相应属性中
如果key是简单的'name',直接form.setName(map.get('name'));
如果key是'account.name', 执行的操作是 form.getAccount().setName(map.get('account.name');
如 果key是'stocks[0].code', 它可以对应到数据或集合中,如对于数组 form.stocks[0].code=map.get('stocks[0].code'); 对于集合((List)form.getStocks()).get(0).setCode(map.get('stocks[0].code'))
从上也能理解为什么 form 中的那两个属性必须实始化,不然会出现空指针错. 而且为什么 stocks 要用 AutoArrayList 实例化, 避免出现索引越界的错误.

: 在 AccountStockAction 中可以打印出提交的数据

 
  1. AccountStockForm asForm = (AccountStockForm)form;  
  2.   
  3. Account account = asForm.getAccount();  
  4. System.out.println("Account Name:" +account.getName()+  
  5.         " Number:" +account.getNumber());  
  6.   
  7. List stocks = asForm.getStocks();  
  8. for  ( int  i= 0 ; i<stocks.size() ;i++)  
  9. {  
  10.     Stock stock = (Stock)stocks.get(i);  
  11.     System.out.println("Stock[" +i+ "]Code:" +stock.getCode()+  
  12.             " Name:" +stock.getName()+  
  13.             " Price:" +stock.getPrice()+  
  14.             " Quantity:" +stock.getQuantity());  
  15. }  
  16.   
  17. return  mapping.findForward( "show" );  



在Action中就能直接取用提交来的数据了,不需要 getParameterValues()了.

: 最后一步, 对于这样的 ActionForm 我们应该如何显示出来呢,我们用了 nested 标签 (show.jsp )

 
  1. < html:form   action = "/showStock" >   
  2.     < h3 > 修改持有的股票 < br > </ h3 >   
  3.     < fieldset > < legend > 基本信息 </ legend >   
  4.     < table   width = "100%"   border = 0 > < tr >   
  5.     < nested:nest   property = "account" >   
  6.         < td > 帐户名: < nested:text   property = "name"   readonly = "true" /> </ td >   
  7.         < td > 资金帐号: < nested:text   property = "number"   readonly = "true" /> </ td >   
  8.     </ nested:nest >   
  9.     </ tr > </ table >   
  10.     </ fieldset >   
  11.     < br >   
  12.     < fieldset > < legend > 持有股票 </ legend >   
  13.     < table   width = 100 border = 0    id = "stockTable" >   
  14.     < tr >   
  15.         < td > < input   type = "checkbox"   onclick = "checkAll(this)" > </ td >   
  16.         < td > 股票代码 </ td >   
  17.         < td > 股票名称 </ td >   
  18.         < td > 成本价 </ td >   
  19.         < td > 股票数量 </ td >   
  20.     </ tr >   
  21.     < nested:iterate   id = "stock"   property = "stocks" >   
  22.     < tr >   
  23.         < td > < input   type = "checkbox"   name = "check" > </ td >   
  24.         < td > < nested:text   property = "code"   size = "15" /> </ td >   
  25.         < td > < nested:text   property = "name"   size = "15" /> </ td >   
  26.         < td > < nested:text   property = "price"   size = "15" /> </ td >   
  27.         < td > < nested:text   property = "quantity"   size = "15" /> </ td >   
  28.     </ tr >   
  29.     </ nested:iterate >   
  30.     </ table >   
  31. </ html:form >   



可以查看生成的HTML源文件, 你就能更好理解 input.jsp 中的表单域为什么要那么命名了.


小结的内容是请注意以下几个重点:
1. 输入信息的页面 input.jsp 没有使用 Struts 标签,目的是让大家理解,表单域应如何命名才能对应上 ActionForm 中的哪一个属性
2. 显示数据的页面是用的 Struts 标签,并留意 nested 标签的应用. 可以从生成的 HTML 源文件中体会出什么
3. 提交数据前要重新编排行层中输入框 Name 属性的下标植.
4. 回味为什么要引入 ArrayList 的子类 AutoArrayList, 关键在 get(int index) 方法的覆写
5. 最后是 ActionForm 中 List 属性 stocks 的 setter 方法的实现, 保持那个 List 的运行时具体类型不变

  • 大小: 33.4 KB
  • 大小: 6.2 KB
分享到:
评论
1 楼 gavin.guo 2012-07-19  
感谢,很实用

相关推荐

    提交多行数据到Struts的ActionForm的List属性中

    这个过程涉及到如何将客户端的数据组织成一个集合,如List,并将其绑定到ActionForm的属性上。在本篇中,我们将详细探讨如何实现这一目标。 首先,ActionForm是Struts框架中用于接收和验证用户输入的数据的类。它...

    struts1.2 from表单提交包含list的对象

    这个Bean应该包含一个List属性,例如`List&lt;Product&gt;`,其中Product是另一个Bean,包含了商品的各个属性。在表单提交后,Struts的默认数据绑定机制会尝试将请求参数自动绑定到ActionForm的属性上。 接着,Action类会...

    Struts中List里嵌套Map

    在ActionForm或Action类中,我们定义一个List变量,并且List的元素类型为Map。例如: ```java private List, String&gt;&gt; productList; // 相应的getter和setter方法 public List, String&gt;&gt; getProductList() { ...

    一个Struts1多文件上传实例(附Form中传List示例)

    例如,我们可以定义一个FileItem类,它包含了文件名、文件内容等信息,并在ActionForm中创建一个List类型的属性,如`private List&lt;FileItem&gt; files;` 在HTML页面中,我们使用Struts1的表单标签库来创建文件上传的...

    struts多文件上传

    这个类包含了两个主要属性:`username`用于存储用户的名称,而`list`则是一个`List`类型的集合,用于存储用户上传的所有文件。 ```java public class UpfileForm extends ActionForm { private String username; ...

    在struts中实现下拉列表

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { YourForm yourForm = (YourForm) form; String ...

    struts操作select标签实例

    这里,`${form.options}`引用了ActionForm中的List,`var="option"`定义了循环变量,`value="${option}"`和`${option}`分别表示选项的值和文本。 另外,对于多选下拉框,可以使用`html:multibox`标签,它的用法与`...

    struts数据传送

    public void setUserList(List&lt;User&gt; userList) { this.userList = userList; } } ``` 3. **填充集合数据**:在 `SampleAction.java` 中,通过查询数据库来填充 `userList`: ```java public ActionForward ...

    自动增长列的编号生成

    public ActionForward addCall(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { ServletContext context = this.getServlet().getServletContext(); //...

    struts1.x html标签 radio,checkbox,multibox,select的使用

    通过`list`属性,可以将选项数据源绑定到ActionForm的属性,从而动态生成选项列表。 在实际应用中,`StrutsMapActionForm`可能是ActionForm的一个实例,它包含了一个或者多个Map对象来存储这些HTML标签的值。例如,...

    Struts批量上传文件实例word

    以下是一个简单的`upload`方法实现,它接收`ActionForm`并从中获取`List&lt;FormFile&gt;`,然后将文件保存到服务器指定的路径: ```java public ActionForward upload(ActionMapping mapping, ActionForm form, ...

    Java Oracle分页处理

    List&lt;PageBean&gt; list = new ArrayList(); newgetResouce newgetresouce = new newgetResouce(); //通过显示页面传递一个pagetype对象和PaginationBean对象 Page page = new Page(request.getParameter(...

    Struts2购物车

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { GoodsDAO dao = new GoodsDAO(); List list = dao.find...

    struts编写的mailreader中文例子

    3. **JSP 页面**:包括登录界面(如`login.jsp`)、邮件列表展示页面(如`mailList.jsp`)和邮件详情页面(如`mailDetail.jsp`)。这些页面通过Struts标签库(例如`&lt;html:form&gt;`、`&lt;logic:iterate&gt;`等)与ActionForm...

    struts1学习文档

    ActionForm类是Struts框架中用于封装表单数据的对象,它继承自`ActionForm`基类。在本例中,`LoginForm`用于封装登录表单的数据,包含用户名和密码字段。通过getter和setter方法提供访问和修改属性值的能力。 ```...

    struts标签的使用(深入潜出).

    `&lt;logic:present&gt;`用来检查ActionForm中的某个属性是否存在或非空,如果`sampleForm`的`userList`属性有值,那么包含它的内容才会被渲染。而`&lt;logic:iterate&gt;`则用于遍历集合属性,如`userList`,对于每个元素(在...

    java面试宝典

    java面试试题 全面 准确 带答案 coreJava部分 8 1、面向对象的特征有哪些方面? 8 2、作用域public,private,protected,以及不写时的区别? 8 3、String 是最基本的数据类型吗? 8 4、float 型float f=3.4是否正确?...

    struts可上传多个文件

    在Struts配置文件(struts-config.xml)中,你需要添加一个定制的`ActionForm`类,该类扩展了`org.apache.struts.action.ActionForm`,并包含用于存储上传文件的属性。 例如,一个简单的`ActionForm`类可能如下所示...

Global site tag (gtag.js) - Google Analytics