`
lijun87
  • 浏览: 268355 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

阅读更多

[转自] http://extjs2.iteye.com/blog/460926

 
今天遇到提交多行数据问题, 在网上找了一点资料:

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

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

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






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

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

一: struts-config.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
    <form-beans>
        <form-bean name="accountStockForm"
          type="com.unmi.form.AccountStockForm"/>
    </form-beans>
    <action-mappings>
        <action path="/showStock" name="accountStockForm"
         type="com.unmi.action.AccountStockAction" scope="request">
            <forward name="show" path="/show.jsp"/>
        </action>
    </action-mappings>
</struts-config>


二: 输入页面 input.jsp, 注意表单域命名
  <html:form action="/showStock">
        <h3>记录持有的股票<br></h3>
        <fieldset>s<legend>基本信息</legend>
        <table width="100%" border=0><tr>
            <td>帐户名:<html:text property="account.name"/></td>
            <td>资金帐号:<html:text property="account.number"/></td>
        </tr></table>
        </fieldset>
        <br>
        <fieldset><legend>持有股票</legend>
        <table width=100% border=0 id="stockTable">
        <tr>
            <td><input type="checkbox" onclick="checkAll(this)"></td>
            <td>股票代码</td>
            <td>股票名称</td>
            <td>成本价</td>
            <td>股票数量</td>
        </tr>
        <tr>
            <td><input type="checkbox" name="check"></td>
            <td><input name="stocks[0].code" size="15"></td>
            <td><input name="stocks[0].name" size="15"></td>
            <td><input name="stocks[0].price" size="15"></td>
            <td><input name="stocks[0].quantity" size="15"></td>
        </tr>
        </table>
    </html:form>



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


三: AccountStockForm 的关键代码

  private Account account = new Account();
    private List stocks = new AutoArrayList(Stock.class);
    
    public void setStocks(List stocks)
    {
        this.stocks.clear();
        this.stocks.addAll(stocks);
    }





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



四: 自定义的 AutoArrayList

public class AutoArrayList extends ArrayList {
    
    private Class itemClass;
    
    public AutoArrayList(Class itemClass) {
        this.itemClass = itemClass;
    }
    
    public Object get(int index) {
        try {
            while (index >= size()) {
                add(itemClass.newInstance());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return super.get(index);
    }
}



理解为什么要继承一个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 中可以打印出提交的数据


  
    AccountStockForm asForm = (AccountStockForm)form;
        
        Account account = asForm.getAccount();
        System.out.println("Account Name:"+account.getName()+
                " Number:"+account.getNumber());
        
        List stocks = asForm.getStocks();
        for (int i=0; i<stocks.size() ;i++)
        {
            Stock stock = (Stock)stocks.get(i);
            System.out.println("Stock["+i+"]Code:"+stock.getCode()+
                    " Name:"+stock.getName()+
                    " Price:"+stock.getPrice()+
                    " Quantity:"+stock.getQuantity());
        }
        
        return mapping.findForward("show");



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

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


    <html:form action="/showStock">
        <h3>修改持有的股票<br></h3>
        <fieldset><legend>基本信息</legend>
        <table width="100%" border=0><tr>
        <nested:nest property="account">
            <td>帐户名:<nested:text property="name" readonly="true"/></td>
            <td>资金帐号:<nested:text property="number" readonly="true"/></td>
        </nested:nest>
        </tr></table>
        </fieldset>
        <br>
        <fieldset><legend>持有股票</legend>
        <table width=100% border=0  id="stockTable">
        <tr>
            <td><input type="checkbox" onclick="checkAll(this)"></td>
            <td>股票代码</td>
            <td>股票名称</td>
            <td>成本价</td>
            <td>股票数量</td>
        </tr>
        <nested:iterate id="stock" property="stocks">
        <tr>
            <td><input type="checkbox" name="check"></td>
            <td><nested:text property="code" size="15"/></td>
            <td><nested:text property="name" size="15"/></td>
            <td><nested:text property="price" size="15"/></td>
            <td><nested:text property="quantity" size="15"/></td>
        </tr>
        </nested:iterate>
        </table>
    </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 的运行时具体类型不变
分享到:
评论

相关推荐

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

    在这个例子中,我们展示了如何通过Struts框架将客户端多行数据转换为ActionForm的List属性,以及如何在服务器端处理这些数据。这是一个常见的需求,特别是在处理批量操作或复杂表单时。了解并熟练掌握这种技巧对于...

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

    在表单提交后,Struts的默认数据绑定机制会尝试将请求参数自动绑定到ActionForm的属性上。 接着,Action类会接收到ActionForm实例,可以通过这个实例获取到用户提交的数据。在处理业务逻辑时,Action可以对这个列表...

    struts中ActionForm的validate方法使用小得

    在Struts中,ActionForm类是处理用户输入数据的核心组件,它封装了请求参数并负责业务逻辑验证。本文将详细讨论如何在Struts中使用ActionForm的`validate`方法进行数据验证。 `validate`方法是在ActionForm中定义的...

    struts ActionForm

    在早期的Struts 1版本中,ActionForm是MVC设计模式中的Model部分,它作为控制器(Controller)与视图(View)之间的桥梁,负责接收、验证和传递用户提交的数据到业务逻辑层。 ActionForm类通常继承自Struts提供的...

    struts 视频 struts视频 actionform

    当用户通过HTML表单提交请求时,这些数据会被发送到服务器,并由Struts框架自动绑定到ActionForm实例的属性上。ActionForm的每个属性对应表单的一个字段,这样就形成了一个对象模型,方便后续业务逻辑处理。 Struts...

    struts1使用actionform实现表单验证

    当用户提交表单时,Struts框架会自动将表单数据绑定到ActionForm实例中。 2. **创建ActionForm** 首先,我们需要创建一个ActionForm类,继承自Struts的`ActionForm`基类。在这个类中,为每个表单字段声明对应的...

    Struts_学习笔记之ActionForm

    在Struts中,ActionForm是继承自JavaBeans的,主要用于处理用户的表单数据和业务逻辑。下面是ActionForm的详细介绍: 1. ActionForm的继承关系 在Struts中,ActionForm继承自JavaBeans,并且提供了两个主要的实现...

    struts中静态ActionForm基本验证

    主要是actionForm的基本验证,重写validate方法,返回actionErrors,然后根据资源文件显示错误。 这是一个demo例子,直接导入eclispe中即可。 并且这部分内容会在相应的博客中介绍,稍后会更新博客。

    actionForm list

    标题“actionForm list”指的是在Struts 1框架中使用ActionForm对象来处理用户请求的列表数据。在Struts 1中,ActionForm是MVC设计模式中的模型部分,它负责收集、验证和封装用户的输入数据,然后传递给Action类进行...

    STRUTS ActionForm乱码,servlet全局过滤器转义编码。

    Struts框架中的ActionForm乱码问题以及Servlet全局过滤器的转义编码处理是Java Web开发中常见的字符编码问题。在开发基于Struts的Web应用时,乱码主要出现在三个方面:页面显示乱码、参数传递乱码以及国际化资源文件...

    Struts高级开发_动态ActionForm.avi

    ActionForm是Struts框架中的一个重要组件,主要用于处理用户从视图层提交的数据。在传统的Struts开发中,ActionForm类通常用于封装请求参数并传递给业务逻辑层进行处理。 动态ActionForm的概念是为了提高代码的灵活...

    验证ActionForm存到了request中

    在用户提交一个HTML表单后,Struts框架会创建一个ActionForm实例,并将表单数据填充到这个实例的属性中。ActionForm类通常包含与表单字段对应的属性和getter、setter方法。例如,如果表单有一个名为"name"的输入字段...

    Struts中List里嵌套Map

    当用户提交表单时,Struts框架会自动将页面上的数据映射到ActionForm或Action类中的相应属性。对于List中的Map,它会根据表单元素的name属性来确定Map的键和值。例如,如果商品的名称输入框的name是`productList[0]....

    ActionForm属性中存在对象数组如何处理

    在Struts框架中,ActionForm类是用于封装请求参数并传递到Action类进行业务逻辑处理的关键组件。当ActionForm中的属性涉及到对象数组时,处理方式就变得稍微复杂一些。以下将详细介绍如何处理ActionForm属性中存在...

    Struts Hibernate Spring 集成开发宝典 actionform

    ActionForm可以被Spring托管,利用Spring的依赖注入,将SessionFactory注入到ActionForm中,以便在业务逻辑处理时执行数据库操作。 集成步骤通常包括以下几个关键点: 1. **配置Struts**: 配置struts-config.xml,...

    Struts中不同的Action和ActionForm组合.rar

    在这个名为“Struts中不同的Action和ActionForm组合.rar”的压缩包中,主要探讨的是Struts框架中Action和ActionForm的组合使用方式,以及它们在处理用户请求和数据验证过程中的作用。以下是对这个主题的详细解释。 ...

    [摘]Struts 学习笔记之ActionForm

    当用户通过表单提交数据时,这些数据会被封装到一个ActionForm实例中,然后由Struts框架将这个实例传递给对应的Action进行业务逻辑处理。ActionForm类通常包含与HTML表单字段相对应的属性,以及对应的getter和setter...

    ActionForm里的get和set方法

    ActionForm是Struts框架中一个关键的组件,它充当了Controller与Model之间的桥梁,负责传递用户在表单中提交的数据到业务逻辑层。本篇文章将深入探讨ActionForm中的get和set方法及其作用。 1. **ActionForm基础** ...

Global site tag (gtag.js) - Google Analytics