Struts2学习笔记八

今天刚学习了Struts2的类型转换器,感觉非常不错

12Struts2的类型转换

 (1). 定义类型转换器

       类型转换器主要用于一个字符串与一个复杂对象之间的相互转换。Struts2的类型转换器是基于OGNL实现的,在OGNL中提供了TypeConverter接口,如果要实现类型转换器则必须实现上述接口。

       TypeConverter接口:

       public interface TypeConverter{

       public Object convertValue(Map context, Object target, Member member,

                     String propertyName, Object value, Class toType);

}

       从上面的接口定义可以看出TypeConverter接口的方法太过于复杂,基于此原因,OGNL提供了一个该接口的实现类:DefaultTypeConverter,可以通过继续该类并重写此类中的convertValue方法来实现自己的类型转换器。

       convertValue方法负责完成类型的转换,这种转换是双向的,可以通过toType的类型来判断转换的方向,toType参数的类型是需要转换的目标类型,如当toTypeUser时表明将字符串转换为User类型;当toTypeString时,表明将User转换为String类型。

       DefaultTypeConverter转换器把所有的请求参数作为字符串数组,而非字符串。

 

 (2). 注册类型转换器

       要使类型转换器起作用,必须要将其注册到WEB应用中,根据注册方式的不同,可以分为以下三种:

l         注册为局部类型转换器;

l         注册为全局类型转换器;

l         使用JDK1.5的注释来注册类型转换器。

要注册局部类型转换器,只需要提供文件名如下格式的文件并放在与相应的Action路径相同的位置:

ActionName-conversion.properties

其中ActionName是需要转换器生效的Action的类名。

其文件内容为:

propertyName = 类型转换器类

ActionName-conversion.properties文件由多个“propertyName = 类型转换器类”组成,其中propertyNameAction中需要类型转换器转换的属性名,类型转换器是用户开发的类型转换器的全限定类名。

例如:user = com.demo.converter.UserConverter

要注册全局类型转换器需要提供一个xwork-conversion.properties文件,其内容由多个“复合类型 = 对应类型转换器”项组成,其中“复合类型”批定需要完成类型转换的复合类,“对应类型转换器”指类型转换器的全限定类名。

       例如:com.demo.User = com.demo.converter.UserConverter

 

 (3). 基于Struts2的类型转换器

       Struts2框架为了简化类型转换器的实现,提供了StrutsTypeConverter抽象类,此类继承自DefaultTypeConverter类,并提供了两个抽象方法:

l         convertFromString(Map context, String[] values, Class toClass);

l         convertToString(Map context, Object o);

 

  (4). 基于OGNL表达式方式的类型转换

       ①.由于Struts2支持OGNL表达式,故我们可以使用另外一种方式来将请求参数转换成复合类型。具体做法是在JSP页面中利用OGNL表达式来直接生成复合类型实例,示例:

       <form action=”Login.do”>

              用户名:

              <input type=”text” name=”user.name” />

              密码:

              <input type=”text” name=”user.password” />

       </formd>

       上述的两个请求参数user.name, user.password,是一种表达式的写法,Struts2会把user.name参数的值赋值给Action实例的user属性的name属性,把user.password参数的值赋给Action实例的user属性的password属性,这样的话就可以把字符串参数直接转换成复合类型对象,使用这种方式时需要注意:

l         必须为复合类型提供无参数的构造器;

l         复合类型必须为要设值的属性提供set方法,同时需要在Action中提供针对该复合类型的set方法。例如,要使用user.nameuser属性的name属性赋值,必须提供setName方法,同时在Action中也必须提供setUser方法。

 

②.Struts2直接将参数封装成Map里的对象

设置JSP表单域的name属性为Action属性名[‘key’].属性名的形式,其中Action属性名是Action类里包含的Map类型属性,最后一个属性名是Map对象里复合类型对象的属性名。

 

 (5). Struts2CollectionMap的支持

       Action属性中若使用了集合类型,如List, Map, Set等的同时,又想让类型转换器起作用的话,有以下两种方法:

l         使用泛型来限制集合里的元素的类型;

l         使用Struts2的局部类型转换配置文件来指定集合元素的数据类型;

下面对局部类型转换配置文件进行说明:

       需要在配置文件中提供以下key-value对:

       Element_xxx = 复合类型

其中Element是固定的,xxxAction中的集合属性名,复合类型是集合元素类型的全限定类名,例如指定Actionaddress集合属性的元素为com.demo.Address实例,代码:

       Element_address = com.demo.Address

 

       如果是Map类型的属性,则需要同时指定Mapkey类型和value类型,指定key类型需要增加:

Key_xxx = 复合类型

其中Key为固定的,xxxMap类型属性的属性名,复合类型指定的是Map属性的key类型的全限定类名;

       指定Map类型属性的value类型,需要增加:

       Element_xxx = 复合类型

 

通过以上设置后,包含集合类型的Action所配置的类型转换器才能正常使用。

JSP上输出List属性的某个元素的值,可以使用如下格式:

<s:property value=”集合属性名[索引].集合元素属性名” />

 

       在集合类中,Set类型的处理是比较特殊的,为了方便访问Set属性中的集合元素,需要指定集合元素的索引属性,这通过在局部类型转换文件中增加如下语句来实现:

       KeyProperty_集合属性名 = 集合元素的索引属性名

其中集合属性名是Action中的集合属性名,集合元素的索引属性名是可以唯一表示集合元素的属性名,例如:

       #指定集合属性users的集合元素类型为com.demo.User

Element_users = com.demo.User

#指定users集合属性里集合元素的索引属性是name

KeyProperty_users = name;

       通过上述配置后,就可以直接通过该索引属性值来访问该集合元素,访问方式为:

              集合属性名(‘索引属性值’)

       例如:访问users集合属性里索引属性值为yuzp的元素的name属性

              users(‘yuzp’).name

 

  (6). 类型转换的错误处理

       Struts2struts-default.xml文件中配置一个conversionError拦截器,如果Struts2的类型转换器在执行转换时出错,该拦截器将负责将对应的错误封装成表单域错误,并放入ActionContext中,然后系统会跳转到input逻辑视图。

       为了输出错误信息,使用标签<s:fielderor/>,错误信息默认为英文,如果需要输出中文出错信息,则需要在资源文件中增加如下代码:

       xwork.default.invalid.fieldvalue = {0}字段类型转换失败!

除此之外,如果想对某一特定字段指定特别的提示信息,则需要提供名为ActionName. propertiesAction局部资源文件,并加入以下代码:

       invalid.fieldvalue.属性名 = 提示信息

其中invalid.fieldvalue为固定值,属性名是Action中属性名

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章