二、Struts 2的类型转换---1.Struts 2中实现自定义的类型转换

Struts 2 的类型转换

1.  传统的类型转换过程。

传统的类型转换过程直接通过servlet取得用户的输入参数,然后翻到Bean中,然后可以直接通过servlet生成输出。大致实现过程如下。

public class Regist extends HttpServlet

{

    public void service(HttpServletRequest request,HttpServletResponse response)throws IOException

{

        request.setCharacterEncoding("GBK");

        String name = request.getParameter("username");

        String pass = request.getParameter("pass");

        String strAge = request.getParameter("age");

        String strBirth = request.getParameter("birth");

 

        int age = Integer.parseInt(strAge);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");

        Date birth = null;

        try

        {

            birth = sdf.parse(strBirth);

        }

        catch (Exception e)

        {

               e.printStackTrace();

        }

        UserBean user = new UserBean(name , pass , age , birth);

 

        response.setContentType("text/html;charset=GBK");

        PrintWriter out = response.getWriter();

        out.println("<html><head><title>");

        out.println("类型转换页面");

        out.println("</title></head><body>");

        out.println("<h1>类型转换页面</h1>");

        out.println(user.getName() + "<br>");

        out.println(user.getPass() + "<br>");

        out.println(user.getAge() + "<br>");

        out.println(user.getBirth() + "<br>");

        out.println("</body></html>");

}

 

    public void destroy()

    {

        super.destroy();

    }

}

 

       正如上面代码,我们先从HttpServletRequest中取出用户输入的参数,然后做一些简单的类型转换后用这些参数去初始化UserBeanUserBean是一个带默认构造函数的POJO。然后是生成输出。显然这样的过程比较繁琐。而且这些步骤都是很程式化的。接下来,我们看以下Struts 2的类型转换器。

 

2.  Struts 2中基于OGNL的类型转换器

Struts 2的类型转换器实际上是基于OGNL实现的。我们先看一下OGNL中提供的TypeConverter接口。

该接口定义如下:

public interface TypeConverter {

       public Object convertValue(Map context, Object target, Member member, String propertyName, Object toType);

}

该接口还有一个实现类:DefaultTypeConverter,我们可以通过继承该类来实现自己的类型转换器。

要继承DefaultTypeConverter类需要重写convertValue方法。

以下是一个示例:

public class UserConverter extends DefaultTypeConverter

{

    public Object convertValue(Map context, Object value, Class toType)

       {

        if (toType == User.class )

              {

                     String[] params = (String[])value;

                     User user = new User();

                     String[] userValues = params[0].split(",");

                     user.setName(userValues[0]);

                     user.setPass(userValues[1]);

                     return user;

 

        }

              else if (toType == String.class )

              {

                     User user = (User) value;

                     return "<" + user.getName() + "," + user.getPass() + ">";

        }

        return null ;

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


我们看到上面的UserConverter继承自 DefaultTypeConverter并重写了 convertValue方法。在convertValue方法中先判断toType是一个User类还是一个String。如果是User,意思就是说要转换得目标类型是User,反之则转换成String。如此,实现UserString之间的相互转换。

上面的实现逻辑并不复杂。那么如何让系统自动去完成这个转换逻辑呢。答案时通过约定的配置文件,把这个转换类和User类联系起来。

根据作用范围的不同分为局部类型转换器和全局类型转换器两种。

局部类型转换器

局部类型转换器的转换逻辑只作用于单个Action的某些属性类。

这个文件的命名规则如下:

ActionName-conversion.propertiesActionName是需要转换器生成的Action的类名,后面的-conversion.properties为固定部分。

这个文件的配置方式也是key-value对。形式如下:

propertyName=类型转换器类

 

比如说我们有个LoginActionAction类,此类中有一个User类的对象user。我们的输入参数是一个以“,”分割的包含User类各属性的String,需要通过上面的UserConverter把输入参数转换成我们需要的User类对象。

那么我们建立一个名为LoginAction-conversion.properties的文件,此文件内容如下。

user=abc.UserConverter

此文件要和LoginAction.class放在同一目录下,既WEB-INF/classes/abc路径下。

如果LoginAction里还有一个User类的对象customer,那么我们再加一行配置语句:

customer=abc.UserConverter

可见局部类型转换器设置的一个Action中每一个对象对应的转换器,如果一个类有多对象则要没个对象都设置一次。显然很麻烦。如果我们想设置User类和UserConverter直接对应起来那么就可以使用全局类型转换器

全局类型转换器

注册一个全局类型转换器要提供一个名为xwork-conversion.properties文件,该文件的内容为复合类型=对应类型转换器。仍然是上面的例子。

建立一个xwork-conversion.properties文件,放在WEB-INF/classes目录下。配置内容如下。

lee.User=lee.UserConverter

该全局类型转换器将会对所有User类型属性起作用。

 

3.  通过StrutsTypeConverter抽象类实现类型转换器

StrutsTypeConverterDefaultTypeConverter的子类。该类中已经重写了convertValue()方法。

 

public abstract class StrutsTypeConverter extends DefaultTypeConverter {
      
      
    public Object convertValue(Map context, Object o, Class toClass) {
      
      
        if (toClass.equals(String.class)) {
      
      
            return convertToString(context, o);
      
      
        } else if (o instanceof String[]) {
      
      
            return convertFromString(context, (String[]) o, toClass);
      
      
        } else if (o instanceof String) {
      
      
            return convertFromString(context, new String[]{(String) o}, toClass);
      
      
        } else {
      
      
            return performFallbackConversion(context, o, toClass);
      
      
        }
      
      
    }
      
      

    
    
     
      
    
    
    protected Object performFallbackConversion(Map context, Object o, Class toClass) {
      
      
        return super.convertValue(context, o, toClass);
      
      
    }
      
      

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

    
    
     
      
    
    
    public abstract String convertToString(Map context, Object o);
      
      
}
      
      

 

还是那前面的例子来说,我们要实现UserConverter只需要重写convertFromString()convertToString()两个方法就可以了。如下:

public class UserConverter extends StrutsTypeConverter {

 

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

              User user = new User();

              String[] userValues = values[0].split(",");

              user.setName(userValues[0]);

              user.setPass(userValues[1]);

              return user;

    }

 

    @Override

    public String convertToString(Map context, Object o){

              User user = (User)o;

              return "<" + user.getName() + "," + user.getPass() + ">";

    }

}

上面的代码应该很容易理解,所以不多解释了。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值