《研磨struts2》第十一章 类型转换 之 11.3 自定义类型转换器

11.3  自定义类型转换器

11.3.1概述

虽然内建类型转换器能满足绝大多数的需求,但是,有的时候还是需要使用自定义类型转换器来实现特定的需求。

还是用前面的长方形来说明,如果用两个文本框分别输入长方形的高和宽,整个类型装换都没有问题,它可以工作的很好。

但是,如果我们想在一个文本框内同时输入宽和高(width:height),形如16:9,这个时候就需要自定义类型转换器了。

11.3.2实现自定义类型转换器

自定义类型转换器的实现非常简单,写一个类,继承StrutsTypeConverter抽象类,该类在org.apache.struts2.util包内,这个抽象类有两个方法需要我们实现:

  • public Object convertFromString(Map context, String[] values, Class toClass)方法,实现字符串向对象的转换,它有三个参数:

l         context:转换上下文,可以在里面引用各种对象,比如:可以通过context.get(ValueStack.VALUE_STACK)来引用值栈。

l         values:用户输入的字符串。

l         toClass:将要被转换成的对象类型。

  • public String convertToString(Map context, Object o)方法,实现对象向字符串的转换,它有两个参数:

l         context:同上,也是转换的上下文。

l         o:需要被转换的对象。

实现示例功能的自定义类型转换器,示例代码如下:

 

java代码:
  1. public class RectangleConverter extends StrutsTypeConverter {  
  2.     /** 
  3.      * 长方形向字符串转换 
  4.      */  
  5.     public Object convertFromString(Map context, String[] values, Class toClass) {  
  6.         //用户输入,比如16:9  
  7.         String userInput = values[0];  
  8.         String[] arr = userInput.split(":");  
  9.         //在真正的格式转换之前,先把所有的用户输入可能的错误拦截住  
  10.         if (arr.length!=2){  
  11.             throw new TypeConversionException("请输入正确的长方形格式如,width:height");  
  12.         }  
  13.         try{  
  14.             Rectangle rectangle = new Rectangle();  
  15.             int width = Integer.parseInt(arr[0]);  
  16.             int height = Integer.parseInt(arr[1]);  
  17.             rectangle.setWidth(width);  
  18.             rectangle.setHeight(height);  
  19.             return rectangle;  
  20.         }catch(RuntimeException e){  
  21.             throw new TypeConversionException("请输入正确的长方形格式如,width:height",e);  
  22.         }  
  23.     }  
  24.     /** 
  25.      * 字符串向长方形转换 
  26.      */  
  27.     public String convertToString(Map context, Object o) {  
  28.         Rectangle rectangle = (Rectangle) o;  
  29.         return "长方形:宽"+rectangle.getWidth()+",高"+rectangle.getHeight();  
  30.     }  
  31. }  

在这里,需要注意在convertFromString方法中,用户输入的字符串很可能是不符合要求的,所有的不符合要求的情况都要抛出TypeConversionException。这是个运行时异常,不需要在方法上声明抛出。

11.3.3注册和引用自定义类型转换器

已经有了自定义类型转换器,应该怎么引用它呢?

1:注册自定义类型转换器

首先要注册这个自定义类型转换器处理。在src下建立一个xwork-conversion.properties文件,这个文件中用“全类名=这个类对应的类型转换器全类名”,来建立类和类型转换器的关系,对于我们来说,只有一行:

 

java代码:
  1. cn.javass.convert.Rectangle=cn.javass.convert.RectangleConverter  

注册完了之后,整个项目所有的长方形,都可以用自定义的类型转换器来处理了。

2:示例用的Action

Action不需要做任何特殊的处理,也就是使用自定义类型转换器的时候,对Action没有影响,请大家记住。对应的Action的示例代码为:

 

java代码:
  1. public class ConverterAction extends ActionSupport {  
  2.     private Rectangle rectangle;  
  3.     public Rectangle getRectangle() {  
  4.         return rectangle;  
  5.     }  
  6.     public void setRectangle(Rectangle rectangle) {  
  7.         this.rectangle = rectangle;  
  8.     }  
  9.       
  10.     public String execute() throws Exception {  
  11.         return SUCCESS;  
  12.     }  
  13. }  

3:修改页面

       那么,使用了自定义类型转换器对哪里有影响呢?对页面有影响,既对提交页面有影响,也对展示页面有影响。

       在提交页面上,不需要再有两个文本框分别对应长方形的高和宽了,只需要一个文本框,而这个文本框对应的不再是长方形的属性(比如rectangle.width或rectangle.height),而是对应整个长方形对象(rectangle)了,而且这个文本框需要按照自定义类型转换器预定的字符串格式填写,这里定义的是宽:高。

提交页面示例代码如下:

 

java代码:
  1. <%@ taglib prefix="s" uri="/struts-tags"%>  
  2. <s:form action="/converterAction.action" method="post">  
  3.     <s:textfield name="rectangle" label="输入长和宽"/>  
  4.     <s:submit value="提交"/>  
  5. </s:form>  

显示结果的页面也需要跟随变动,示例代码如下:

 

java代码:
  1. <%@ taglib prefix="s" uri="/struts-tags" %>  
  2. <s:property value="rectangle"/>  

4:测试

       运行测试一下,在输入页面的文本框中填入16:9,然后点击提交,Action就可以正确接到这个长方形对象,然后转向输出页面,显示如下:

图11.1  示例自定义转换器

在展示页面上使用的<s:property value="rectangle"/>,就可以显示出自定义类型转换器中convertToString方法的返回值了。

注意:<s:property value="rectangle"/>这句话会引用自定义类型转换器,因为这时候要把一个字符串转换成Rectangle对象,而前面<s:textfield name=” rectangle.width”/>则不会引用自定义转换器,因为它只是要把一个字符串转换成Rectange对象的width属性而已,实际上只需要转换为int。

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4100.html

欢迎访问http://sishuok.com获取更多内容

猜你喜欢

转载自rubbing-struts2.iteye.com/blog/1541677