`
徜徉の小溪
  • 浏览: 448147 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

转换器(Converter)Struts 2.0中

阅读更多


2011-04-28 13:12

转换器(Converter)——Struts 2.0中的魔术师 
在我已往的Struts 1.x项目经验中,有个问题不时的出现——在创建FormBean时,对于某个属性到底应该用String还是其它类型?
开发Web应用程序与开发传统桌面应用程序不同,Web应用程序实际上是分布个不同的主机(当然也可以同一个主机,不过比较少见)上的两个进程之间互交。这种互交建立在HTTP之上,它们互相传递是都是字符串。换句话说, 
服务器可以的接收到的来自用户的数据只能是字符串或字符数组,而在服务器上的对象中,这些数据往往有多种不同的类型,如日期(Date),整数(int),浮点数(float)或自定义类型(UDT)等,如图1所示。因此,我们需要服务器端将字符串转换为适合的类型。

 
同样的问题也发生在使用UI展示服务器数据的情况。HTML的Form控件不同于桌面应用程序可以表示对象,其值只能为字符串类型,所以我们需要通过某种方式将特定对象转换成字符串。
要实现上述转换,Struts 2.0中有位魔术师可以帮到你——Converter。有了它,你不用一遍又一遍的重复编写诸如此类代码:
Date birthday = DateFormat.getInstance(DateFormat.SHORT).parse(strDate);
<input type="text" value="<%= 
DateFormat.getInstance(DateFormat.SHORT).format(birthday) %>" />
好了,现在让我们来看一个例子。
转换器——Hello World
在我的上一篇文章《在Struts 2.0中国际化(i18n)您的应用程序》的最后我举了一个可以让用户方便地切换语言的例子,下面例子与其相似,但实现方法不同。
首先,如《在Struts 2.0中国际化(i18n)您的应用程序》的第一个例子一样,创建和配置默认的资源文件;
接着,新建源代码文件夹下的tutorial包创建HelloWorld.java文件,代码如下:

package tutorial;
import java.util.Locale;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
public class HelloWorld extends ActionSupport   {
      private String msg;
      private Locale loc = Locale.US;
   
      public String getMsg()   {
          return msg;        
     } 
    
      public Locale getLoc()   {
          return loc;
     } 
    
      public void setLoc(Locale loc)   {
          this .loc = loc;
     } 
    
     @Override
      public String execute()   {
          // LocalizedTextUtil是Struts 2.0中国际化的工具类,<s:text>标志就是通过调用它实现国际化的 
         msg = LocalizedTextUtil.findDefaultText( " HelloWorld " , loc);
          return SUCCESS;
     } 
} 
 

然后,在源代码文件夹下的struts.xml加入如下代码新建Action:

< package name ="ConverterDemo" extends ="struts-default" > 
     < action name ="HelloWorld" class ="tutorial.HelloWorld" > 
         < result > /HelloWorld.jsp </ result > 
     </ action > 
</ package > 
 
再在Web文件夹下,新建 HelloWorld.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 ="HelloWorld" theme ="simple" >            
         Locale: < s:textfield name ="loc" /> &nbsp; < s:submit /> 
     </ s:form >    
     < h2 >< s:property value ="msg" /></ h2 > 
</ body > 
</ html > 
 
接下来,在源代码文件夹的tutorial包中新建LocaleConverter.java文件,代码如下:

package tutorial;
import java.util.Locale;
import java.util.Map;
public class LocaleConverter extends ognl.DefaultTypeConverter   {
     @Override
      public Object convertValue(Map context, Object value, Class toType)   {
          if (toType == Locale. class )   {
             String locale = ((String[]) value)[ 0 ];
              return new Locale(locale.substring( 0 , 2 ), locale.substring( 3 
));
         } else if (toType == String. class )   {
             Locale locale = (Locale) value;
              return locale.toString();
         } 
          return null ;
     } 
} 
 

再接下来,在源代码文件夹下新建xwork-conversion.properties,并在其中添加如下代码:

java.util.Locale = tutorial.LocaleConverter 
发布运行应用程序,在浏览器中键入http://localhost:8080/Struts2_Converter/HelloWorld.action,输出页面如图2所示:

>
在Locale输入框中输入“zh_CN”,按“Submit”提交,出现如图3所示页面:

>
上述例子中,Locale文本输入框对应是Action中的类型为java.util.Locale的属性loc,所以需要创建一个自定义转变器实现两者间的转换。所有的Struts 
2.0中的转换器都必须实现ognl.TypeConverter接口。 
为了简单起见,OGNL包也为你提供了ognl.DefaultTypeConverter类去帮助您实现转换器。在例子中,LocaleConverter继承了ognl.DefaultTypeConverter,重载了其方法原型为“public 
Object convertValue(Map context, Object value, Class toType)”的方法。下面简单地介绍一下函数的参数:

   context——用于获取当前的ActionContext 
   value——需要转换的值 
   toType——需要转换成的目标类型 
实现转换器,我们需要通过配置告诉Struts 2.0。我们可以通过以下两种方法做到这点: 
   配置全局的类型转换器,也即是上例的做法——在源代码文件夹下,新建一个名为“xwork-conversion.properties”的配置文件,并在文件中加入“待转换的类型的全名(包括包路径和类名)=转换器类的全名”对;
   应用于某个特定类的类型转换器,做法为在该类的包中添加一个格式为“类名-conversion.properties”的配置文件,并在文件中加入“待转换的属性的名字=转换器类的全名”对。上面的例子也可以这样配置——在源代码文件夹的tutorial包下新建名为“HelloWorld-conversion.properties”文件,并在其中加入“loc=tutorial.LocaleConverter”。
       在继承DefaultTypeConverter时,如果是要将value转换成其它非字符串类型时,要记住value是String[]类型,而不是String类型。它是通过request.getParameterValues(String 
       arg)来获得的,所以不要试图将其强行转换为String类型。

已有的转换器
对于一此经常用到的转换器,如日期、整数或浮点数等类型,Struts 2.0已经为您实现了。下面列出已经实现的转换器。 
   预定义类型,例如int、boolean、double等; 
   日期类型, 使用当前区域(Locale)的短格式转换,即DateFormat.getInstance(DateFormat.SHORT);
   集合(Collection)类型, 将request.getParameterValues(String 
   arg)返回的字符串数据与java.util.Collection转换;
   集合(Set)类型, 与List的转换相似,去掉相同的值;
   数组(Array)类型, 将字符串数组的每一个元素转换成特定的类型,并组成一个数组。
对于已有的转换器,大家不必再去重新发明轮子。Struts在遇到这些类型时,会自动去调用相应的转换器。
批量封装对象(Bean)
不知道大家是否遇过这种情况,在一个页面里同时提交几个对象。例如,在发布产品的页面,同时发布几个产品。我在之前一个项目就遇到过这种需求,当时用的是Struts 
1.x。那是一个痛苦的经历,我在Google搜了很久都没有理想的结果。幸运的是,在Struts 2.0中这种痛苦将一去不复返。下面我就演示一下如何实现这个需求。
首先,在源代码文件夹下的tutorial包中新建Product.java文件,内容如下:

package tutorial;
import java.util.Date;
publicclass Product {
     private String name;
     privatedouble price;
     private Date dateOfProduction;
    
     public Date getDateOfProduction() {
         return dateOfProduction;
     }
    
     publicvoid setDateOfProduction(Date dateOfProduction) {
         this.dateOfProduction = dateOfProduction;
     }
    
     public String getName() {
         return name;
     }
    
     publicvoid setName(String name) {
         this.name = name;
     }
    
     publicdouble getPrice() {
         return price;
     }
    
     publicvoid setPrice(double price) {
         this.price = price;
     }    
}
 

然后,在同上的包下添加ProductConfirm.java类,代码如下:

package tutorial;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
publicclass ProductConfirm extends ActionSupport {
     public List<Product> products;
     public List<Product> getProducts() {
         return products;
     }
     publicvoid 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所示,填写表单,按“Submit”提交,出现图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
上面的代码并不复杂,但有几点需要说明: 
   ProductConfirm文件中的for(Product p : productes)的写法是J2SE 5.0中的新特性,作用遍历products列表;
   List<Product>也是J2SE 5.0的才有的泛型(Generic);
   ProductConfirm-conversion.properties中“Element_products=tutorial.Product”是告诉Struts 
   2.0列表products的元素的类型为Product,而不是定义转换器; 
   在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所示:

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

<div style="color:red">
     <s:fielderror />
</div>
刷新浏览器,重新提交请求,出现如图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应用程序的模型,为我们的编程带来极大的方便。

0
1
分享到:
评论

相关推荐

    struts2.0中文教程

    05 转换器(Converter)——Struts 2.0中的魔术师 06 在Struts 2.0中实现表单数据校验(Validation) 07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts...

    Struts 2.0系列(MAX)

    转换器(Converter)——Struts 2.0中的魔术师 在Struts 2.0中实现表单数据校验(Validation) Struts 2的基石——拦截器(Interceptor) 在Struts 2中实现IoC 在Struts 2中实现文件上传 在Struts 2中实现CRUD ...

    Struts2.0中文教程权威版

    05 转换器(Converter)——Struts 2.0中的魔术师 06 在Struts 2.0中实现表单数据校验(Validation) 07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts...

    Struts_2.0从入门到精通

    五、转换器(Converter)在Struts2.0中的作用 转换器是Struts2.0框架中的一个重要概念,它负责将请求参数转换为Java类型的数据。Struts2.0内置了一系列的转换器,如默认转换器、日期转换器等,同时也支持自定义转换...

    转换器(Converter)——Struts 2.0中的魔术师

    在Struts 2.0框架中,转换器(Converter)扮演着至关重要的角色,它是将用户界面提交的数据转化为模型对象属性的关键组件。Struts 2的魔术师——转换器,使得数据绑定变得更加灵活和强大,它能处理各种类型的数据...

    struts2.0很全面的中文教程

    1.为Struts 2.0做好准备 2.常用的Struts 2.0的标志(Tag)介绍 3.Struts 2.0的Action讲解 ...5.转换器(Converter)——Struts 2.0中的魔术师 在6.Struts 2.0中实现表单数据校验(Validation) 7....... 8.......

    struts 2.0 自定义类型转换器 注册类型转换器 入门实例 简单实例

    在Struts 2中,类型转换器(Type Converter)扮演着至关重要的角色,它负责将HTTP请求中的字符串数据转换为应用程序所需的对象类型。当我们需要对默认类型转换器的功能进行扩展或者处理自定义类型时,就需要自定义...

    struts2.0开发最精简教程 转换器篇

    Struts2.0是Java Web开发中非常流行的一个MVC框架,它极大地简化了Web应用程序的构建过程。在Struts2中,转换器(Converter)扮演着数据绑定和格式化的重要角色,使得开发者能够对输入的数据进行有效控制和处理。本...

    个人认为目前最完备的Struts2教程

    05 转换器(Converter)——Struts 2.0中的魔术师 06 在Struts 2.0中实现表单数据校验(Validation) 07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts...

    struts2.0小例子

    在这个"struts2.0小例子"中,我们可以深入探讨Struts2.0的关键特性和用法。 1. **核心概念** - **Action**:Struts2中的Action类是业务逻辑的执行者,负责接收请求、处理数据并返回结果。 - **Result**:Action...

    struts2.0简明教程

    这个教程涵盖了从框架的初步安装到实际开发中的常见功能,包括Action、标签(Tag)、转换器(Converter)、数据校验(Validation)、国际化(i18n)、文件上传、AJAX集成以及CRUD操作等多个关键点。 1. **Struts ...

    Struts2.0学习笔记.doc

    文档中的内容主要涉及到Struts2.0的类型转换机制,特别是对于自定义类型转换器的使用。 首先,Struts2.0内置了一些预定义的类型转换,例如基本数据类型(int, Boolean, double等)以及日期类型。对于日期类型,它会...

    对Struts 2.0中的struts.xml配置文件详细说明 2

    Struts 2.0是Java Web开发中广泛使用的MVC框架,它的核心在于`struts.xml`配置文件。这个配置文件扮演着应用的中枢角色,负责定义动作(Actions)、结果(Results)、拦截器(Interceptors)等关键组件,以及它们...

    struts2入门教程

    ·Struts2.0转换器(Converter) ·Struts 2.0中实现表单数据校验(Validation) ·拦截器(Interceptor) ·Struts 2中实现IoC ·Struts 2中实现文件上传 ·Struts 2中的OGNL ·Strus 2的新表单标签的使用 ...

    struts2.0经典案例下载

    Struts2.0是一款强大的Java Web开发框架,它在MVC设计模式的基础上,为开发者提供了构建Web应用程序的强大工具。这个经典案例集包含了Struts2框架的一些核心功能的实践示例,如输入验证、文件上传、拦截器的使用以及...

    Struts 2 自学入门教程

    转换器(Converter)在Struts 2中负责将用户输入的数据转换为应用程序所需的格式。例如,将字符串转换为日期或数字。转换器可以通过全局或Action级别进行配置,提供灵活的数据验证和转换机制。 转换与校验...

    DWR2.0中文文档

    - **Converter**:定义如何将Java对象转换为JSON格式,如HibernateBeanConverter用于处理Hibernate实体。 - **标签**:定义服务接口的方法签名,用于客户端验证。 #### 整合 - **DWR与Servlet**:DWR可以通过...

    struts2如何配置与自定义类型转换

    如果你只想为特定的Action中的某个字段创建类型转换器,你需要创建一个类继承自`StrutsTypeConverter`,并在Action所在的同一个包下创建一个属性文件,如`Action的名字-conversion.properties`。例如,如果你有一个...

    struts2教程pdf清晰版

    “5 converter.pdf”涉及Struts2的转换器,它们负责将用户输入的数据转换为适合业务处理的格式。这部分将涵盖Converter接口的实现,以及自动转换机制的配置。 “6 validation.pdf”可能涵盖Struts2的验证框架,包括...

Global site tag (gtag.js) - Google Analytics