本站首页    管理页面    写新日志    退出


«September 2025»
123456
78910111213
14151617181920
21222324252627
282930


公告
本博客在此声明所有文章均为转摘,只做资料收集使用。并无其他商业用途。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:210
评论数量:205
留言数量:-19
访问次数:920204
建立时间:2007年5月10日




[struts2]转换器(Converter)——Struts 2.0中的魔术师
文章收藏,  网上资源,  软件技术,  电脑与网络

李小白 发表于 2007/11/9 21:58:23

在我已往的Struts 1.x项目经验中,有个问题不时的出现——在创建FormBean时,对于某个属性到底应该用String还是其它类型? 开发Web应用程序与开发传统桌面应用程序不同,Web应用程序实际上是分布个不同的主机(当然也可以同一个主机,不过比较少见)上的两个进程之间互交。这种互交建立在HTTP之上,它们互相传递是都是字符串。换句话说, 服务器可以的接收到的来自用户的数据只能是字符串或字符数组,而在服务器上的对象中,这些数据往往有多种不同的类型,如日期(Date),整数(int),浮点数(float)或自定义类型(UDT)等,如图1所示。因此,我们需要服务器端将字符串转换为适合的类型。 500)this.width=500'> 图1 UI与服务器对象关系 同样的问题也发生在使用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文件,代码如下: 500)this.width=500'> package tutorial;500)this.width=500'>500)this.width=500'> import java.util.Locale;500)this.width=500'>500)this.width=500'> import com.opensymphony.xwork2.ActionSupport;500)this.width=500'> import com.opensymphony.xwork2.util.LocalizedTextUtil;500)this.width=500'>500)this.width=500'>500)this.width=500'> public class HelloWorld extends ActionSupport 500)this.width=500'> {500)this.width=500'>     private String msg;500)this.width=500'>     private Locale loc = Locale.US;500)this.width=500'>   500)this.width=500'>500)this.width=500'>     public String getMsg() 500)this.width=500'> {500)this.width=500'>         return msg;        500)this.width=500'>    } 500)this.width=500'>    500)this.width=500'>500)this.width=500'>     public Locale getLoc() 500)this.width=500'> {500)this.width=500'>         return loc;500)this.width=500'>    } 500)this.width=500'>    500)this.width=500'>500)this.width=500'>     public void setLoc(Locale loc) 500)this.width=500'> {500)this.width=500'>         this .loc = loc;500)this.width=500'>    } 500)this.width=500'>    500)this.width=500'>    @Override500)this.width=500'>500)this.width=500'>     public String execute() 500)this.width=500'> {500)this.width=500'>         // LocalizedTextUtil是Struts 2.0中国际化的工具类,<s:text>标志就是通过调用它实现国际化的 500)this.width=500'>        msg = LocalizedTextUtil.findDefaultText( " HelloWorld " , loc);500)this.width=500'>         return SUCCESS;500)this.width=500'>    } 500)this.width=500'>} 然后,在源代码文件夹下的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文件,代码如下: 500)this.width=500'> package tutorial;500)this.width=500'>500)this.width=500'> import java.util.Locale;500)this.width=500'> import java.util.Map;500)this.width=500'>500)this.width=500'>500)this.width=500'> public class LocaleConverter extends ognl.DefaultTypeConverter 500)this.width=500'> {500)this.width=500'>    @Override500)this.width=500'>500)this.width=500'>     public Object convertValue(Map context, Object value, Class toType) 500)this.width=500'> {500)this.width=500'>500)this.width=500'>         if (toType == Locale. class ) 500)this.width=500'> {500)this.width=500'>            String locale = ((String[]) value)[ 0 ];500)this.width=500'>             return new Locale(locale.substring( 0 , 2 ), locale.substring( 3 ));500)this.width=500'>500)this.width=500'>        } else if (toType == String. class ) 500)this.width=500'> {500)this.width=500'>            Locale locale = (Locale) value;500)this.width=500'>             return locale.toString();500)this.width=500'>        } 500)this.width=500'>         return null ;500)this.width=500'>    } 500)this.width=500'>} 再接下来,在源代码文件夹下新建xwork-conversion.properties,并在其中添加如下代码: java.util.Locale = tutorial.LocaleConverter 发布运行应用程序,在浏览器中键入http://localhost:8080/Struts2_Converter/HelloWorld.action,输出页面如图2所示:500)this.width=500'>图2 HelloWorld英文输出 在Locale输入框中输入“zh_CN”,按“Submit”提交,出现如图3所示页面:500)this.width=500'>图3 HelloWorld中文输出 上述例子中,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”。 500)this.width=500'> 在继承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文件,内容如下: 500)this.width=500'>package tutorial;500)this.width=500'>500)this.width=500'>import java.util.Date;500)this.width=500'>500)this.width=500'>500)this.width=500'>publicclass Product 500)this.width=500'>{500)this.width=500'>    private String name;500)this.width=500'>    privatedouble price;500)this.width=500'>    private Date dateOfProduction;500)this.width=500'>    500)this.width=500'>500)this.width=500'>    public Date getDateOfProduction() 500)this.width=500'>{500)this.width=500'>        return dateOfProduction;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>500)this.width=500'>    publicvoid setDateOfProduction(Date dateOfProduction) 500)this.width=500'>{500)this.width=500'>        this.dateOfProduction = dateOfProduction;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>500)this.width=500'>    public String getName() 500)this.width=500'>{500)this.width=500'>        return name;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>500)this.width=500'>    publicvoid setName(String name) 500)this.width=500'>{500)this.width=500'>        this.name = name;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>500)this.width=500'>    publicdouble getPrice() 500)this.width=500'>{500)this.width=500'>        return price;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>500)this.width=500'>    publicvoid setPrice(double price) 500)this.width=500'>{500)this.width=500'>        this.price = price;500)this.width=500'>    }    500)this.width=500'>} 然后,在同上的包下添加ProductConfirm.java类,代码如下: 500)this.width=500'>package tutorial;500)this.width=500'>500)this.width=500'>import java.util.List;500)this.width=500'>500)this.width=500'>import com.opensymphony.xwork2.ActionSupport;500)this.width=500'>500)this.width=500'>500)this.width=500'>publicclass ProductConfirm extends ActionSupport 500)this.width=500'>{500)this.width=500'>    public List<Product> products;500)this.width=500'>500)this.width=500'>500)this.width=500'>    public List<Product> getProducts() 500)this.width=500'>{500)this.width=500'>        return products;500)this.width=500'>    }500)this.width=500'>500)this.width=500'>500)this.width=500'>    publicvoid setProducts(List<Product> products) 500)this.width=500'>{500)this.width=500'>        this.products = products;500)this.width=500'>    }500)this.width=500'>    500)this.width=500'>    @Override

阅读全文(1871) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.254 second(s), page refreshed 144777152 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号