温馨提示:您的每一次转载,体现了我写此文的意义!!!烦请您在转载时注明出处http://www.blogjava.net/sxyx2008/谢谢合作!!!

雪山飞鹄

温馨提示:您的每一次转载,体现了我写此文的意义!!!烦请您在转载时注明出处http://www.blogjava.net/sxyx2008/谢谢合作!!!

BlogJava 首页 新随笔 联系 聚合 管理
  215 Posts :: 1 Stories :: 674 Comments :: 0 Trackbacks

原理

struts2的自定义类型转换机制为复杂类型的输入输出处理提供了便捷.struts2已经为我们提供了几乎所有的primitive类型以及常用类型(Date)的类型转换器,我们也可以为我们自定义类添加自定义类型转化器.

struts2为我们提供了一个类型转化器的入口: ognl.DefaultTypeConverter,或继承org.apache.struts2.util.StrutsTypeConverter,由于StrutsTypeConverter提供了更好的封装,所以建议大家在写转换器时通常采用继承StrutsTypeConverter方式来实现.

StrutsTypeConverter类实质上是DefaultTypeConverter的扩展

 publicabstractclass StrutsTypeConverter extends DefaultTypeConverter

{

}

StrutsTypeConverter中的两个核心方法

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

publicabstract String convertToString(Map context, Object o);

convertFromString方法用于从前台页面获取字符串,将字符串转化为对象

convertToString方法用于将对象以字符串的方式输出到页面

我们在写struts2自定义类型转换类的时候主要就是覆盖上面两个方法

分类

struts2自定义类型转换从大的方面来讲分两种:

u      局部类型转换

u      全局类型转换

局部类型转换又分为三种:

²       普通实体bean的自定义类型转换

²       基于领域模型的自定义类型转换

²       基于模型驱动的自定义类型转换

无论是全局类型转换还是局部类型转换,转换器与Action之间是用properties文件来关联的,properties文件指明了转换规则

       全局类型转换规则:

       classpath下新建文件xwork-conversion.properties(固定名称)

       其内容为:目标转换对象=转换器类(包名+类名)

       局部类型转换规则:

       在对应的Action的同级目录下新建Action-conversion.properties(一定要与Action类名对应)

       其内容为: 目标转换对象=转换器类(包名+类名)

       在局部类型转换中又存在一种特殊情况

       基于领域模型的自定义类型转换

   它不但要在对应的Action的同级目录下新建Action-conversion.properties(一定要与Action类名对应)文件,还需在引用模型同级目录下建properties文件取名规则为引用名- conversion.properties

这块不好用文字描述,举个列子:

需求是这样的:

User类中有个Point对象的引用,现在要基于Point来做自定义类型转换,这里PointUser之间的这层关系就叫做领域模型,在操作User时需要对Point进行自定义类型转换,这时就必须在User类的同级目录下新建User-conversion.properties文件,在文件中指明point对象需要用什么类来进行转换.

我们约定Point类的对象名就为point,而对应的转换类为com.dl.convertor.PointConvertor,对应的Action类为PointUserAtion, PointUserAtion中有一个User类型的属性名为user

那么在PointUserAtion的同级目录中会存在一个名为PointUserAtion-conversion.properties的文件其内容为:

user.point= com.dl.convertor.PointConvertor

//因为在Action中引用的对象名为user而现在要处理的是user中的point属性,所以这里需要使用user.point来指明

同样在User类的同级目录会存在一个名为User-conversion.properties的文件内容为

point=com.dl.convertor.PointConvertor

//因为该文件只针对user,所以只需指明User中的point对象即可不需在添加user否则会出现预想不到的结果

针对局部类型转换三种情况的例子

  ²       普通实体bean类型转换

   实体bean(Point)

/**

 *普通的javabean封装坐标

 */

publicclass Point {

   privateintx;

   privateinty;

//省略set get方法

}

对应的Action(PointAction)

publicclass PointAction extends ActionSupport{

   private Point point;

//省略set get方法

   public String execute() throws Exception {

      returnsuper.execute();

   }

}

对应的转换类(PointConvertor)

publicclass PointConvertor extends StrutsTypeConverter{

   /**

    *从表单中的stringPoint对象

    *我们约定以,来分隔这里为了严谨期间最好要进行输入数据的验证

    */

   @Override

   public Object convertFromString(Map context, String[] str, Class c) {

      Point point=null;

      if(str!=null||str.length>0){

        String[] s=str[0].split(",");

        point=new Point();

        int x=Integer.parseInt(s[0]);

        int y=Integer.parseInt(s[1]);

        point.setX(x);

        point.setY(y);

      }

      return point;

   }

   /**

    *从对象到字符串

    *比如页面输出

    */

   @Override

   public String convertToString(Map context, Object o) {

      Point point=(Point)o;

      return"("+point.getX()+","+point.getY()+")";

   }

}

需要做的配置:PointAction的同级目录下新建PointAction-conversion.properties,文件内容为

#目标转换对象=转换器

point=com.dl.convertor.PointConvertor



²      
领域模型自定义类型转换

实体bean(Point,User)

 publicclass User {

   private String name;

   private Point point;

//省略set get方法

}

publicclass Point {

   privateintx;

   privateinty;

//省略set get方法

}

对应的Action(PointAction)

public class UserAction extends ActionSupport{

   private User user;

//省略set get方法

   @Override

   public String execute() throws Exception {

      return super.execute();

   }

}

对应的转换类(PointConvertor)

publicclass PointConvertor extends StrutsTypeConverter{

   /**

    *从表单中的stringPoint对象

    *我们约定以,来分隔这里为了严谨期间最好要进行输入数据的验证

    */

   @Override

   public Object convertFromString(Map context, String[] str, Class c) {

      Point point=null;

      if(str!=null||str.length>0){

        String[] s=str[0].split(",");

        point=new Point();

        int x=Integer.parseInt(s[0]);

        int y=Integer.parseInt(s[1]);

        point.setX(x);

        point.setY(y);

      }

      return point;

   }

   /**

    *从对象到字符串

    *比如页面输出

    */

   @Override

   public String convertToString(Map context, Object o) {

      Point point=(Point)o;

      return"("+point.getX()+","+point.getY()+")";

   }

}

需要做的配置:

UserAction的同级目录下新建UserAction-conversion.properties,文件内容为

#目标转换对象=转换器

user.point=com.dl.convertor.PointConvertor

User的同级目录下新建User-conversion.properties,文件内容为

point=com.dl.convertor.PointConvertor

        
²      
模型驱动自定义类型转换
实体bean(Point)

/**

 *普通的javabean封装坐标

 */

publicclass Point {

   privateintx;

   privateinty;

//省略set get方法

}

对应的Action(PointModelDrivenAction)

/**

 * 基于模型驱动的自定义类型转换

 * @author Administrator

 *

 */

@SuppressWarnings("serial")

public class PointModelDrivenAction extends ActionSupport implements ModelDriven<Point>{

   private Point point;

   public Point getPoint() {

      return point;

   }

   public void setPoint(Point point) {

      this.point = point;

   }

   public Point getModel() {

      return point;

   }

   @Override

   public String execute() throws Exception {

      return super.execute();

   }

}

:这里切记要生成pointset get方法要不值不能自动进行封装

对应的转换类(PointConvertor)

publicclass PointConvertor extends StrutsTypeConverter{

   /**

    *从表单中的stringPoint对象

    *我们约定以,来分隔这里为了严谨期间最好要进行输入数据的验证

    */

   @Override

   public Object convertFromString(Map context, String[] str, Class c) {

      Point point=null;

      if(str!=null||str.length>0){

        String[] s=str[0].split(",");

        point=new Point();

        int x=Integer.parseInt(s[0]);

        int y=Integer.parseInt(s[1]);

        point.setX(x);

        point.setY(y);

      }

      return point;

   }

   /**

    *从对象到字符串

    *比如页面输出

    */

   @Override

   public String convertToString(Map context, Object o) {

      Point point=(Point)o;

      return"("+point.getX()+","+point.getY()+")";

   }

}

需要做的配置:

PointModelDrivenAction的同级目录下新建PointModelDrivenAction-conversion.properties,文件内容为

#目标转换对象=转换器

point=com.dl.convertor.PointConvertor

User的同级目录下新建User-conversion.properties,文件内容为

point=com.dl.convertor.PointConvertor




    至此
Struts2的自定义类型转换你基本已经掌握了,还不赶紧动手练练.遇到什么问题,请及时遇我联系

QQ:184675420     Blog:http://www.blogjava.net/sxyx2008/

Email:sxyx2008@gmail.com

demo下载:http://www.blogjava.net/Files/sxyx2008/struts2typeconvertor.zip
      电子文档下载:点我下载电子版文档.pdf

posted on 2010-01-12 14:37 雪山飞鹄 阅读(10570) 评论(8)  编辑  收藏 所属分类: struts2

Feedback

# re: Struts2自定义类型转换 2010-01-12 16:19 struts2爱好者
总结的很全面,看的出博主是认真研究过的  回复  更多评论
  

# re: Struts2自定义类型转换 2010-01-12 16:21 struts2
图文结合,内容很丰富,受益了  回复  更多评论
  

# re: Struts2自定义类型转换 2010-01-13 10:08 小猴子
LZ回避了一个问题:如果坐标分别是在两个文本框输入的情况。这时如果转换异常,返回时如何在原页面显示?  回复  更多评论
  

# re: Struts2自定义类型转换 2010-01-13 12:45 雪山飞鹄
@小猴子
这个问题好解决嘛,在前台页面文本框输入处为文本框分别取名为point.x,point.y 然后在后台页面分别获取point.x,point.y的值然后封装成point对象不就解决了.这与用一个文本框接受坐标输入然后用逗号来分隔原理是一样的嘛   回复  更多评论
  

# re: Struts2自定义类型转换 2010-03-07 22:39 当当
非常好,一直困扰的问题在你这里解决了,最好再写一篇struts2模型驱动下的XML验证示例  回复  更多评论
  

# re: Struts2自定义类型转换 2012-05-25 16:54 胖墩儿
呵呵 对我很有用!  回复  更多评论
  

# re: Struts2自定义类型转换[未登录] 2013-04-02 23:05 A
DFS  回复  更多评论
  

# re: Struts2自定义类型转换[未登录] 2013-04-02 23:05 A
FS  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: