无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

package tutorial;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class ProductConfirm extends ActionSupport {
   
public List < Product > products;

   
public List < Product > getProducts() {
       
return products;
   }


   
public void setProducts(List < Product > products) {
       
this .products = products;
   }

   
   @Override
   
public String execute() {
       
for (Product p : products) {
           System.out.println(p.getName()
+ " | " + p.getPrice() + " | " + p.getDateOfProduction());
       }

       
return SUCCESS;
   }

}

接看,在同上的包中加入ProductConfirm-conversion.properties,代码如下:

Element_products = tutorial.Product

再在struts.xml文件中配置ProductConfirm Action,代码片段如下:

< action name ="ProductConfirm" class ="tutorial.ProductConfirm" >
   
< result > /ShowProducts.jsp </ result >
</ action >

在WEB文件夹下新建AddProducts.jsp,内容如下:

<% @ page  contentType = " text/html; charset=UTF-8 " %>
<% @taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
   
< title > Hello World </ title >
</ head >
< body >
   
< s:form action ="ProductConfirm" theme ="simple" >            
       
< table >
           
< tr style ="background-color:powderblue; font-weight:bold;" >
               
< td > Product Name </ td >
               
< td > Price </ td >
               
< td > Date of production </ td >
           
</ tr >
           
< s:iterator value ="new int[3]" status ="stat" >
               
< tr >
                   
< td >< s:textfield name ="%{'products['+#stat.index+'].name'}" /></ td >
                   
< td >< s:textfield name ="%{'products['+#stat.index+'].price'}" /></ td >
                   
< td >< s:textfield name ="%{'products['+#stat.index+'].dateOfProduction'}" /></ td >
               
</ tr >
           
</ s:iterator >
           
< tr >
               
< td colspan ="3" >< s:submit /></ td >
           
</ tr >
       
</ table >
   
</ s:form >    
</ body >
</ html >

在同样的文件夹下创建ShowProducts.jsp,内容如下:

<% @ page  contentType = " text/html; charset=UTF-8 " %>
<% @taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
   
< title > Hello World </ title >
</ head >
< body >    
   
< table >
       
< tr style ="background-color:powderblue; font-weight:bold;" >
           
< td > Product Name </ td >
           
< td > Price </ td >
           
< td > Date of production </ td >
       
</ tr >
       
< s:iterator value ="products" status ="stat" >
           
< tr >
               
< td >< s:property value ="name" /></ td >
               
< td > $ < s:property value ="price" /></ td >
               
< td >< s:property value ="dateOfProduction" /></ td >
           
</ tr >
       
</ s:iterator >
   
</ table >
</ body >
</ 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 21 00 : 00 : 00 CST 2004
Pro Spring |
32.99 | Mon Jan 31 00 : 00 : 00 CST 2005
Core J2EE Patterns: Best Practices and Design Strategies
, Second Edition | 34.64 | Sat May 10 00 : 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中加入以下代码:

< 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),而出错的行则会被赋为页面所提交的错误值,这样可以提供更好的用户体验。

总结

Struts 2.0的转换器简化的WEB应用程序的模型,为我们的编程带来极大的方便。

posted on 2006-11-07 14:26 Max 阅读(571) 评论(2)  编辑 收藏引用收藏至365Key 所属分类: Struts 2.0系列


凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

posted on 2006-11-08 22:57 草儿 阅读(288) 评论(0)  编辑  收藏 所属分类: java

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


网站导航: