struts2自定义类型转换器

大多数情况下只需要使用Struts2提供的类型转换器以及基于OGNL的类型转换机制就能满足大部分类型转换需求。但是如果需要把一个字符串转换成一个复合对象(例如User对象)时,这就需要使用自定义类型转换器。例如,用户输入一个admin,12345字符串,我们需要将其转换成一个User类型实例,其中admin作为User实例的name属性值,12345作为User实例的password属性值。

如图:


我们就需要定义一个自定义类型转换器,来完成这个需求。

Action类代码
package com.test.action;
import com.opensymphony.xwork2.Action;
import com.test.dao.User;
public class LoginAction implements Action{
    //封装请求参数的Map对象
    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    //处理用户请求的execute方法
    public String execute() throws Exception {
        // 调用user属性的name、password进行判断
        if(getUser().getName().equals("admin")
                &&getUser().getPassword().equals("12345")){
            return SUCCESS;
        }else{
            return ERROR;
        }
    }

}


User类的代码

package com.test.dao;
public class User {
    private String name;
    private String password;
    public User() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}


Struts2的类型转换器实际上也是基于OGNL实现的,在OGNL项目中有一个TypeConverter接口,这个接口就是实现类型转换器必须实现的接口。

publicinterface TypeConverter {
    public Object convertValue(Map context, Object target, Member member,
            String propertyName, Object value, Class toType);
}

不过上面接口里的方法太复杂了,所以OGNL项目还提供了一个该接口的实现类:DefaultTypeConverter,通过继承该类来实现自己的类型转换器。实现自定义类型转换器需要重写DefaultTypeConverter类的convertValue方法。

本应用所使用的类型转换器UserConverter如下
package com.test.action;

import java.util.Map;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
import com.test.dao.User;
//通过继承DefaultTypeConverter来实现类型转换器
public class UserConverter extends DefaultTypeConverter{
    //类型转换器必须重写convertValue方法,该方法需要完成双向转换。通过判断toType参数的类型即可判断转换的方向
    public Object convertValue(Map context,Object value,Class toType){
        //toType类型是需要转换的目标类型
        //当需要将字符串向User类型转换时
        if(toType==User.class){
            //系统的请求参数是一个字符串数组
            String[] params=(String[]) value;
            //创建一个User实例
            User user=new User();
            //只处理请求参数数组的第一个数组元素,并将该字符串以英文逗号分割成两个字符串
            String[] userValues=params[0].split(",");
            //为User实例赋值
            user.setName(userValues[0]);
            user.setPassword(userValues[1]);
            //返回转换来的User实例
            return user;
        }
        //当需要将User实例转换成字符串时
        else if(toType==String.class){
            //将需要转换的值强制类型转换为User实例
            User user=(User) value;
            return "<"+user.getName()+","+user.getPassword()+">";
        }
        return null;
    }

}
convertValue方法介绍

作用:该方法负责完成类型的转换,这种转换是双向的。通过判断toType参数的类型即可实现判断转换的方向。toType类型是需要转换的目标类型,当toType类型是User类型时,表明需要将字符串转换成User实例;当toType类型是String类型时,表明需要将User实例转换成字符串类型。

参数和返回值的意义:

该方法有三个参数

1、context是类型转换环境的上下文

2、value是需要转换的参数。随着转换方向的不同,value参数的值也是不一样的,当把字符串类型向User类型转换时,value是原始字符串数组;当需要把User类型转换成字符串类型时,value是User实例。

3、toType是转换后的目标类型。

该方法的返回值就是类型转换后的值,该值的类型也会随转换方向的不同而不同,当需要把字符串向User类型转换时,返回值类型就是User类型;当需要把User类型向字符串类型转换时,返回值类型就是字符串类型。

由此可见,转换器的convertValue方法,接收需要转换的值,需要转换的目标类型为参数,然后返回转换后的目标值 实现了自定义类型转换器之后,将该类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器。

类型转换器注册的方式有三种:

1、注册局部类型转换器:局部类型转换器仅仅对某个Action的属性起作用。

2、注册全局类型转换器:全局类型转换器对所有Action的特定类型的属性都会生效。

3、使用JDK1.5的Annotation来注册类型转换器

局部类型转换器的注册

要注册局部类型转换器只需要提供文件名为如下格式的文件即可。

ActionName-conversion.properties:ActionName是需要转换器生效的Action的类名,而后的字符串则是固定部分。
对于上面的LoginAction类,应该提供的类型转换器注册文件的文件名为:LoginAction-conversion.properties,该文件是一个典型的Properties文件,文件由key-value对组成。文件内容为:propertyName=类型转换器类

本应用所使用的LoginAction-conversion.properties文件

user=com.test.action.UserConverter

至此,局部类型转换器注册成功。

如果在用户信息输入框中输入“admin,12345”字符串,根据类型转换器的作用,它会将admin解析成User实例的name属性,12345将被作为User实例的password属性。如图

局部类型转换器只对指定Action的特定属性起作用,这具有很大的局限性。通常我们会将类型转换器注册成全局类型的转换器,让该类型转换器对该类型的所有属性起作用。

下图所示的输入页面,包含三个请求参数,其中用户信息和客人信息都需要转换成User类型,而生日参数则需要转换成Date类型。

Action类

package com.test.action;
import java.util.Date;
import com.opensymphony.xwork2.Action;
import com.test.dao.User;
public class LoginAction implements Action{
    //使用类型转换器将字符串请求参数直接转换成一个User实例
    private User user;
    //封装customer请求参数的属性
    private User customer;
    //封装birth请求参数的属性
    private Date birth;
    //无参构造函器
    public LoginAction() {
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

    public User getCustomer() {
        return customer;
    }
    public void setCustomer(User customer) {
        this.customer = customer;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    //处理用户请求的execute方法
    public String execute() throws Exception {
        // 调用user属性的name、password进行判断
        if(getUser().getName().equals("admin")
                &&getUser().getPassword().equals("12345")){
            return SUCCESS;
        }else{
            return ERROR;
        }
    }
}

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

下面是本应用中注册全局类型转换器的注册文件代码
com.test.dao.User=com.test.action.UserConverter

一旦注册了上面的全局类型转换器,该全局类型转换器就会对所有的User类型属性起作用

在用户信息输入框中输入“admin,12345”,在客人信息输入框中输入“abc,def”,在生日输入框中输入“2013-01-10”,然后提交请求,将看到如下所示


局部类型转换器对指定Action的指定属性起作用,一个属性只调用convertValue方法一次。全局类型转换器对所有Action的特定类型起作用,因此可能对一个属性多次调用convertValue方法进行转换--当该属性是一个数组或集合时,该数组或集合中包含几个该类型的元素,那就会调用几次convertValue方法。







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值