Web应用程序的交互都是建立在HTTP之上的,互相传递的都是字符串。也就是说服务器接收到的来自用户的数据只能是字符串或者是字符数组,而在Web应用的对象中,往往使用了多种不同的类型,如整数(int)、浮点数(float)、日期(Date)或者是自定义数据类型等。因此在服务器端必须将字符串转换成合适的数据类型。
Struts2框架中为我们提供了一些简单类型的转换器,比如转换为int、float等简单数据类型是不需要我们自己定义转换器去转换的,struts2内部本身就为我们提供了转换的方法,但像一些复杂的类型和我们自定义的数据类型还是需要我们自己去写转换器去转换的。在转换工程中,如果在类型转换中出现异常,类型转换器开发者无需关心异常处理逻辑,Struts2的conversionError拦截器会自动处理该异常,并且提示在页面上生成提示信息。
一、自定义类型转换器。
比如我们想把20131010转换成Date格式。
首先定义一个类DateTypeConverter继承DefaultTypeConverter 重写里面的converterValue方法、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package cn.lpq.type.converter import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter; public vlass DateTypeConverter extends DefaultTypeConverter{ public Object converValue (Map<String,Object> context,Object value,Class toType){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); try{ if(toType == Data.class){ //当字符串向Date类型转换时 String[] params = (String[]) value; //Request.getParameterValues() return dateFormat.parse(params[0]); }else if(toType == String.class){ //当date转换成字符串时 Date date = (Date)value; return dateFormat.format(date); } }catch(ParseException e){ return null; } } } |
二、注册自定义类型转换器
实现了自定义的类型转换器之后,将该类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器,类型转换器的注册分为两种,
1.注册局部类型转换器。
局部类型转换器仅仅对某个Action起作用。局部类型转换器非常简单,只需要在相应的Action目录下新建一个资源文件。该资源文件名格式如下。ActionName-conversion.properties。其中ActionName表示需要进行转换的Action的类名,“-conversion.properties”字符串则是固定格式的。该文件也是一个典型Properties文件,文件由键值对组成:propertyName = 类型转换器类
如:name=util.NameConvert
name:表示要进行转换的属性
util.NameConvert:表示要进行转换的自定义类型转换器。
注意:该属性文件应该与ActionName.class放在相同位置。
2.注册全局类型转换器。对所有Action的特定类型的属性都会生效。
全局类型转换器,必须提供一个xwork-conversion.properties文件。文件必须保存在classes目录下。该资源文件名格式如下:
复合类型=对应的类型转换器
复合类型:指定需要完成类型转换的复合类
对应的类型转换器:指定所指定类型转换的转换器。
如:注册User类的全局类型转换器为:UserConverter
cn.wjz.bean.User = cn.wjz.util.UserConverter
注意:如果局部类型转换和全局类型转换同时存在的话,局部类型转换具有较高的优先级,也就是以局部类型转换器为主。
三.集合类型的类型转换
对于List元素来说,内容如: Element_attributeName=typeName;
对于Map元素来说,
(1)如果表示key的类型,则:Key_attributeName=typeName;
(2)如果表示value的类型,则为:Element_attributeName=typeName;
四.Struts 2内建的类型转换器 :
Sturts 2为常用的数据类型提供了内建的类型转换器,所以根本不用自定义转换器。对于内建的转换器,Struts在遇到这些类型时,会自动去调用相应的转换器进行类型转换。
Struts 2全部的内建转换器:
·基本数据类型以及其封装类。包括:boolean和Boolean、char和Character、int和Integer、long和Integer、float和Float、double和Double。完成字符串和基本数据类型或其封装类之间的转换。
·日期类型。使用当前区域的短格式转换,即DateFormat.getInstance(DateFormat.SHORT)完成字符串和日期类型之间的转换。
·集合(Collection)类型。将request.getParameterValues(String arg)返回的字符串数据与java.util.Collection转换。集合元素为String类型。
·集合(Set)类型。与Collection的转换相似,只是去掉了相同的值。集合元素为String类型。
·数组类型。将request.getParameterValues(String arg)返回的字符串数组中的每个字符串值取出组成一个数组。数组元素为String类型。
注意:Struts 2提供的全部内建转换器都是双向的,也就是说从用户输入页到服务器端时会将字符串类型转换成相应的数据类型。在显示输出时,又会将相应的数据类型转换成字符串类型来显
数组类型的转换器。这个转换器非常有用,比如多个表单元素的name属性相同,那么提交的参数就不再是字符串而是一个字符串数组。通过Sturts 2提供的数组类型的转换器就能很方便的将多个相同name属性的表单元素的值封装到Action中的一个数组中。
五.类型转换中错误处理:
1.类型转换的错误处理流程:
Struts2提供了一个名为conversionError的拦截器,这个拦截器被注册在默认的拦截器栈中,在Struts.xml中的配置信息:
1 2 3 4 5 6 7 8 | <interceptor-stack name="defaultStack"> .. .. .. <!—- 处理类型转换错误的拦截器 --> <interceptor-ref name="conversionError"/> </interceptor-stack> |
如果Struts2的类型转换器执行类型转换时出现错误,该拦截器将负责将对应的错误封装成表单域错误(fieldError),并将这些错误信息放入ActionContext中。
Struts2的错误处理流程:
2、错误信息的友好显示
在进行类型转换中,如果出现错误将会提示错误信息。Struts 2默认提供了错误信息提示,但是这些错误信息提示不够友好,下面将介绍如何自定义错误信息来取代Struts 2的默认错误信息。
·定义全局类型转换错误处理信息:
在应用的国际化资源文件中增加如下的信息:
xwork.default.invalid.fieldvalue = key
key的值就是用户希望在页面中显示的提示信息。 例如:
#改变默认的类型转换失败后的提示信息
xwork.default.invalid.fieldvalue = {0}字段类型转换失败!!
因为包含非西欧字符,因此使用 native2ascii 命令处理
xwork.default.invalid.fieldvalue =
{0}\u5b57\u6bb5\u7c7b\u578b\u8f6c\u6362\u5931\u8d25\uff01\uff01
·定义局部类型转换错误处理信息:
在某些时候可能还需要对特定的字段指定特别的提示信息,此时可以提供该Action的局部资源文件,文件名:ActionName.properties , 在文件中增加如下一项:
invalid.fieldvalue.属性名 =提示信息
例如:
#改变Action中birth属性类型转换错误后的提示信息
invalid.fieldvalue.birth = 生日信息必须满足yyyy-MM-DD格式
使用 native2ascii 命令处理
invalid.fieldvalue.birth =
\u751f\u65e5\u4fe1\u606f\u5fc5\u987b\u6ee1
\u8db3yyyy-MM-DD\u683c\u5f0f
六.类型转换的流程
1、用户进行请求,根据请求名在struts.xml中寻找Action
2、在Action中,根据请求域中的名字去寻找对应的set方法。找到后在赋值之前会检查这个属性有没有自定义的类型转换。没有的话,按照默认进行转换;如果某个属性已经定义好了类型转换,则会去检查在Action同一目录下的action文件名-conversion.properties文件。
3、从文件中找到要转换的属性及其转换类。
4、然后进入转换类中,在此类中判断转换的方向。我们是先从用户请求开始的,所以这时先进入从字符串到类的转换。返回转换后的对象。流程返回Action。
5、将返回的对象赋值给Action中的属性,执行Action中的execute()
6、执行完execute()方法,根据struts.xml的配置转向页面
7、在jsp中显示内容时,根据页面中的属性名去调用相应的get方法,以便输出
8、在调用get方法之前,会检查有没有此属性的自定义类型转换。如果有,再次跳转到转换类当中。
9、在转换类中再次判断转换方向,进入由类到字符串的转换,完成转换后返回字符串。
10、将返回的值直接带出到要展示的页面当中去展示。
除非注明,Coder文章均为原创,转载请以链接形式标明本文地址