第七节:Struts2-类型转换

类型转换的作用:

实现了表示层与逻辑层数据类型之间的转换。(JSP页面只有String类型,Action层有各种类型),这种数据转换可以放在Action处理类中实现,因为几乎每个Action都涉及到数据转换所以抽出来做了自动(基本类型、OGNL表达式)的类型转换拦截器。

1.处理请求参数

将JSP页面(也可能是其他视图类型)提交的数据(字符串类型),转换成Action中设定的复杂类型属性。

JSP页面中有一个提交属性叫“name”,提交表单后经过类型转换拦截器。拦截器将根据"name"属性名查找目标Action中name属性。根据name属性的类型调用不同的类型转换方法,利用name属性值创建name对象。再通过setName()方法为Action中name属性赋值。

2.处理响应参数

将Action中设定的复杂类型属性,转换成JSP页面(也可能是其他视图类型)中的字符串类型。

Action中有一个"name"属性,根据name类型调用不同的类型转换方法,将name复杂类型转换成字符串(类似于调用了toString()方法)。将转换后的name(字符串类型)保存到ActionContext上下文中。在JSP页面中时候则从ActionContext中获取。


一般情况:表示层一个属性对应逻辑层一个字段。如果字段是基本类型则可以自动转换。

例如:表示层属性loginUser,对应逻辑层loginUser属性。

  表示层一个属性对应逻辑层一个复杂对象的一个属性。可以将属性指向复杂对象的一个属性则可以自动转换。

例如:表示层属性user.username,对应逻辑层user对象的username属性。

要求复杂对象必须包含空构造方法,要求复杂对象的属性必须包含get、set方法。

特殊情况:表示层一个属性对应逻辑层一个复杂对象,则需要使用到自定义类型转换。

例如:表示层属性user要求输入格式“username,password”信息,逻辑层由一个user属性对应。

这时需要一个自定义类型转换器对两端的数据进行搭桥(互相转换)。

例如:表示层属性maps的值是一个Map.toString()的结果。逻辑层由一个Map属性对应。

这时需要一个自定义类型转换器对两端的数据进行搭桥(互相转换)。


如何自定义类型转换器

方法一比较复杂

实现TypeConverter接口,实现convertValue(Map context,Object target,Member member,String propertyName,Object value,Class toType);方法。

方法二

继承DefaultTypeConverter类,实现convertValue(Map context,Object value,Class toType)方法。

详解:

1.conventValue方法作用很简单,该方法负责完成类型的转换,不过这种转换是双向的;当需要把字符串转换成User对象时,当需要把User对象转换成字符串时,均通过该方法实现。

通过判断toType的类型即可判断转换的方向。可能是Struts或者User。

2.convertValue方法参数和返回值的意义。

第一个参数:context是类型转换环境的上下文。

第二个参数:value是需要转换的参数。User-->String时value表示User实例。String-->User时value表示请求参数字符串数组。

第三个参数:toType是转换后的目标类型。

返回值:当User-->String时返回值类型是String,String-->User时返回值类型是User。

3.为何当String-->User时value表示一个数组而不是一个字符串。因为在表单提交时多个相同的名称表示一组数据(多个值)需要用数组或集合接受。所以为满足这种情况value的类型是数组。

方法三

继承StrutsTypeConverter类,实现以下两个方法:

//实现将字符串类型转换成复杂类型的方法

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

//实现将复杂类型转换成字符串类型的方法

public String convertToString(Map context,Object o);


自定义类型转换与集合的关系

对于MAP、LIST、SET有各自的配置文件要编写,但个人感觉只需要使用OGNL表达式即可输出想要的结果。待测试。


类型转换与异常处理

在类型转换过程中可能发生错误并抛出异常后,conversionError拦截器将拦截异常(之前提到过),将转换错误封装成fieldError,并将其放在ActionContext中。最后跳转到input指定的物理映射页面(需要提前在struts.xml中配置)。

在JSP页面中需要使用<s:fielderror/>标签输出该类型转换错误信息。

效果:在input指定的页面中出现 Invalid field value for field 属性名 的提示信息。很不友好。

修改错误提示信息

Invalid field value for field 属性名 :包含两部分“Invalid field value for field”固定值和 "属性名"动态值。

修改固定值:

通过在国际化配置文件中添加:xwork.default.invalid.fieldvalue={0}字段类型转换失败!

修改动态值:在页面中显示属性名还是很不友好。

创建配置文件

ActionName.properties:ActionName表示需要处理的Action类名。

编写配置文件

#为某个Action特定属性指定特定的校验失败提示信息

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

存放配置文件

与需要处理的Action同一目录

PS:当出错的是一个数组内元素时,提示信息只能做到提示数组有问题。无法指出是那条信息错误了。















如何部署设置自定义类型转换器

设置局部类型转换器:局部类型转换器仅仅对某个Action的属性起作用。

设置全局类型转换器:全局类型转换器对所有Action的特定类型的属性都会生效。

使用JDK1.5D的注释来注册类型转换器(略)。

局部配置:

创建配置文件

ActionName-conversion.properties:ActionName是需要转换器生效的Action类名。其他部分是固定值。

编写配置文件

#指定Action类中user属性需要使用lee.UserConverter类来完成类型转换。

user=lee.UserConverter

存放配置文件

配置文件与Action类放在同一个目录下。

全局配置:

创建配置文件

xwork-conversion.properties文件

编写配置文件

#指定lee.User类的类型转换由lee.UserConverter类处理。

lee.User=lee.UserConverter

存放配置文件

与struts.xml文件同目录下。




















































































  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值