老钟

并不是每一次雨后,都会有彩虹
posts - 14, comments - 4, trackbacks - 0, articles - 1
不知道大家是否遇过这种情况,在一个页面里同时提交几个对象。例如,在发布产品的页面,同时发布几个产品。 
首先,在源代码文件夹下的tutorial包中新建Product.java文件,内容如下: 
 1 package tutorial;
 2 
 3 import java.util.Date;
 4 
 5 publicclass Product {
 6     private String name;
 7     privatedouble price;
 8     private Date dateOfProduction;
 9     
10     public Date getDateOfProduction() {
11         return dateOfProduction;
12     }
13     
14     publicvoid setDateOfProduction(Date dateOfProduction) {
15         this.dateOfProduction = dateOfProduction;
16     }
17     
18     public String getName() {
19         return name;
20     }
21     
22     publicvoid setName(String name) {
23         this.name = name;
24     }
25     
26     publicdouble getPrice() {
27         return price;
28     }
29     
30     publicvoid setPrice(double price) {
31         this.price = price;
32     }    
33 }
然后,在同上的包下添加ProductConfirm.java类,代码如下: 
 1 package tutorial;
 2 
 3 import java.util.List;
 4 
 5 import com.opensymphony.xwork2.ActionSupport;
 6 
 7 publicclass ProductConfirm extends ActionSupport {
 8     public List<Product> products;
 9 
10     public List<Product> getProducts() {
11         return products;
12     }
13 
14     publicvoid setProducts(List<Product> products) {
15         this.products = products;
16     }
17     
18     @Override
19     public String execute() {
20         for(Product p : products) {
21             System.out.println(p.getName() + " | "+ p.getPrice() +" | " + p.getDateOfProduction());
22         }
23         return SUCCESS;
24     }
25 }
接看,在同上的包中加入ProductConfirm-conversion.properties,代码如下:
1 Element_products=tutorial.Product
再在struts.xml文件中配置ProductConfirm Action,代码片段如下: 
1 <action name="ProductConfirm" class="tutorial.ProductConfirm">
2     <result>/ShowProducts.jsp</result>
3 </action>  
在WEB文件夹下新建AddProducts.jsp,内容如下:
 1 <%@ page  contentType="text/html; charset=UTF-8"%>
 2 <%@taglib prefix="s" uri="/struts-tags"%>
 3 <html>
 4 <head>
 5     <title>Hello World</title>
 6 </head>
 7 <body>
 8     <s:form action="ProductConfirm" theme="simple">            
 9         <table>
10             <tr style="background-color:powderblue; font-weight:bold;">
11                 <td>Product Name</td>
12                 <td>Price</td>
13                 <td>Date of production</td>
14             </tr>
15             <s:iterator value="new int[3]" status="stat">
16                 <tr>
17                     <td><s:textfield name="%{'products['+#stat.index+'].name'}"/></td>
18                     <td><s:textfield name="%{'products['+#stat.index+'].price'}"/></td>
19                     <td><s:textfield name="%{'products['+#stat.index+'].dateOfProduction'}"/></td>
20                 </tr>
21             </s:iterator>
22             <tr>
23                 <td colspan="3"><s:submit /></td>
24             </tr>
25         </table>
26     </s:form>    
27 </body>
28 </html>
在同样的文件夹下创建ShowProducts.jsp,内容如下:
 1 <%@ page  contentType="text/html; charset=UTF-8"%>
 2 <%@taglib prefix="s" uri="/struts-tags"%>
 3 <html>
 4 <head>
 5     <title>Hello World</title>
 6 </head>
 7 <body>    
 8     <table>
 9         <tr style="background-color:powderblue; font-weight:bold;">
10             <td>Product Name</td>
11             <td>Price</td>
12             <td>Date of production</td>
13         </tr>
14         <s:iterator value="products" status="stat">
15             <tr>
16                 <td><s:property value="name"/></td>
17                 <td>$<s:property value="price"/></td>
18                 <td><s:property value="dateOfProduction"/></td>
19             </tr>
20         </s:iterator>
21     </table>
22 </body>
23 </html>
发布运行应用程序,在浏览器中键入http://localhost:8080/Struts2_Converter/AddProducts.jsp,出现如图4所示页面: 
图4 添加产品页面 
图4 添加产品页面 
按图4所示,填写表单,按“Submit”提交,出现图5所示页面: 
图5 查看产品页面 
图5 查看产品页面 
查看服务器的控制台,有如下输出: 
Expert One-on-One J2EE Development without EJB | 39.99 | Mon Jun 2100:00:00 CST 2004
Pro Spring | 32.99 | Mon Jan 3100:00:00 CST 2005
Core J2EE Patterns: Best Practices and Design Strategies, Second Edition | 34.64 | Sat May 1000:00:00 CST 2003

上面的代码并不复杂,但有几点需要说明:

  1. ProductConfirm文件中的for(Product p : productes)的写法是J2SE 5.0中的新特性,作用遍历products列表;
  2. List<Product>也是J2SE 5.0的才有的泛型(Generic);
  3. ProductConfirm-conversion.properties中“Element_products=tutorial.Product”是告诉Struts 2.0列表products的元素的类型为Product,而不是定义转换器;
  4. 在AddProducts.jsp的<s:textfield>的name为“%{'products['+#stat.index+'].name'}”,%{exp}格式表示使用OGNL表达式,上述表达式的相当于<%= "products[" + stat.index + "].name" %>,至于<s:iterator>标志的用法可以参考原文主人博客的文章《常用的Struts 2.0的标志(Tag)介绍》。

     

转换错误处理

不知道大家在运行上面的例子时,有没有填错日期或数字情况,又或者您有没有思考过这种情况?如果还没有尝试的朋友可以试一下,在第一行的Price和Date of production中输入英文字母,然后按“Submit”提交。你会看到页面为空白,再看一下服务器的控制台输出,有如下语句: 警告: No result defined for action tutorial.ProductConfirm and result input,它提示我们没有为Action定义输入结果,所以,我们应该在源代码文件夹下的struts.xml中的ProductConfirm Action中加入以下代码: 

1 <result name="input">/AddProducts.jsp</result>

重新加载应用程序,刷新浏览器重新提交请求,这时页面返回AddProducts.jsp,格式错误的输入框的值被保留,如下图6所示: 
图6 没有提示的错返回页面 
 图6 没有提示的错返回页面

当然,我们还可以在页面上加上错误提示信息,通过在AddProducts.jsp的“<body>”后,加入下面代码可以实现: 
<div style="color:red">
    
<s:fielderror />
</div> 

刷新浏览器,重新提交请求,出现如图7所示页面: 
图7 带提示的错返回页面 
图7 带提示的错返回页面 
以上的功能的都是通过Struts 2.0里的一个名为conversionError的拦截器(interceptor)工作,它被注册到默认拦截器栈(default interceptor stack)中。Struts 2.0在转换出错后,会将错误放到ActionContext中,在conversionError的作用是将这些错误封装为对应的项错误(field error),因此我们可以通过<s:fielderror />来将其在页面上显示出来。另外,大家看第二和第三行的Price都被赋为0.0的值,而第一行则保留其错误值。这同样是conversionError的功劳——没有出错的行调用的products[index].price(默认值为0.0),而出错的行则会被赋为页面所提交的错误值,这样可以提供更好的用户体验。 

上文中,还需要编写一个转换器,用于格式化日期输入输出!
本文转自Max,更加详细请看原文《转换器(Converter)——Struts 2.0中的魔术师


------------------------------------------------------
About Me's
                ------一个喜欢在一块青石阶上独立行走的人

Feedback

# re: Struts 2.0——Converter转换器——批量封装对象(Bean)[未登录]  回复  更多评论   

2012-04-07 23:18 by lyh
我确实也遇到了这样的问题,谢了!

只有注册用户登录后才能发表评论。


网站导航: