首页 存档 技术 查看内容

Java程序员从笨鸟到菜鸟之(四十四)细谈struts2(七)数据类型转换详解

2018-3-30 13:00 |来自: 互联网 297 0

摘要: 【新朋友】点击标题下面(↑)蓝色字“Java那些事”关注 【老朋友】点击右上角,转发或分享本页面内容 Web应用程序的交互都是建立在HTTP之上的,互相传递的都是字符串。也就是说服务器接收到的来自用户的数据只能是 ...

【新朋友】点击标题下面(↑)蓝色字“Java那些事”关注

【老朋友】点击右上角,转发或分享本页面内容


Web应用程序的交互都是建立在HTTP之上的,互相传递的都是字符串。也就是说服务器接收到的来自用户的数据只能是字符串或者是字符数组,而在Web应用的对象中,往往使用了多种不同的类型,如整数(int)、浮点数(float)、日期(Date)或者是自定义数据类型等。因此在服务器端必须将字符串转换成合适的数据类型。

Struts2框架中为我们提供了一些简单类型的转换器,比如转换为intfloat等简单数据类型是不需要我们自己定义转换器去转换的,struts2内部本身就为我们提供了转换的方法,但像一些复杂的类型和我们自定义的数据类型还是需要我们自己去写转换器去转换的。在转换工程中,如果在类型转换中出现异常,类型转换器开发者无需关心异常处理逻辑,Struts2conversionError拦截器会自动处理该异常,并且提示在页面上生成提示信息。

下面我们就一步步的实现和注册一个我们自己的转换器,也就是自定义类型转换器的几个步骤:

一:自定义类型转换器

实现自定义类型转换器我们一般有两种方式:

1.实现OGNL提供的TypeConvert接口以及实现了TypeConvert接口的DefaultTypeConvert类来实现自定义的类型转换器。我们来看一下DefaultTypeConvert类的源码:

[java] view plaincopyprint?

  1. publicclass DefaultTypeConverter implements TypeConverter{

  2. public DefaultTypeConverter(){

  3. super();

  4. }

  5. /**

  6. * @param context:类型转换的上下文

  7. * @param value:需要转换的参数

  8. * @param toType:转换后的目的类型

  9. */

  10. public Object convertValue(Map context,

  11. Object value,

  12. Class toType)

  13. {

  14. return OgnlOps.convertValue(value, toType);

  15. }

  16. public Object convertValue(Map context, Object target,

  17. Member member, String propertyName,

  18. Object value, Class toType)

  19. {

  20. return convertValue(context, value, toType);

  21. }

  22. }

convertValue方法的作用:

该方法负责完成类型的双向转换,为了实现双向转换,我们通过判断toType的类型即可判断转换的方向。toType类型是需要转换的目标类型如:当toType类型是User类型时,表明需要将字符串转换成User实例;当toType类型是String类型时,表明需要把User实例转换成字符串类型。通过toType类型判断了类型转换的方向后,我们就可以分别实现两个方向的转换逻辑了。实现类型转换器的关键就是实现conertValue方法,该方法有三个参数:

第一个参数 context:类型转换的上下文

第二个参数 value:需要转换的参数

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

2. 基于Struts2的类型转换器

Struts 2提供了一个StrutsTypeConverter的抽象类,这个抽象类是DefaultTypeConverter的子类。开发时可以直接继承这个类来进行转换器的构建。通过继承该类来构建类型转换器,可以不用对转换的类型进行判断(和第一种方式的区别),下面我们来看一下StrutsTypeConverter类的源码:

[java] view plaincopyprint?

  1. publicabstractclass StrutsTypeConverter extends DefaultTypeConverter {

  2. //重写DefaultTypeConverter类的convertValue方法

  3. public Object convertValue(Map context, Object o, Class toClass) {

  4. //如果需要把复合类型转换成字符串类型

  5. if (toClass.equals(String.class)) {

  6. return convertToString(context, o);

  7. }

  8. //如果需要把字符串转换成符合类型

  9. elseif (o instanceof String[]) {

  10. return convertFromString(context, (String[]) o, toClass);

  11. }

  12. //如果需要把字符串转换成符合类型

  13. elseif (o instanceof String) {

  14. return convertFromString(

  15. context, new String[]{(String) o}, toClass);

  16. } else {

  17. return performFallbackConversion(context, o, toClass);

  18. }

  19. }

  20. protected Object performFallbackConversion(Map context,

  21. Object o, Class toClass) {

  22. returnsuper.convertValue(context, o, toClass);

  23. }

  24. publicabstract Object convertFromString(Map context,

  25. String[] values, Class toClass);

  26. publicabstract String convertToString(Map context, Object o);

  27. }

该类已经实现了DefaultTypeConverter的convertValue方法。实现该方法时,它将两个不同转换方向替换成不同方法当需要把字符串转换成复合类型时,调用convertFromString抽象方法;当需要把复合类型转换成字符串时,调用convertToString抽象方法,下图展示了其对应关系:



二.注册自定义类型转换器:

实现了自定义的类型转换器之后,将该类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器,类型转换器的注册分为两种

1.注册局部类型转换器。

局部类型转换器仅仅对某个Action起作用。局部类型转换器非常简单,只需要在相应的Action目录下新建一个资源文件。该资源文件名格式如下。ActionName-conversion.properties。其中ActionName表示需要进行转换的Action的类名,“-conversion.properties”字符串则是固定格式的。该文件也是一个典型Properties文件,文件由键值对组成:propertyName = 类型转换器类

如:name=util.NameConvert

name:表示要进行转换的属性

util.NameConvert:表示要进行转换的自定义类型转换器。

注意:该属性文件应该与ActionName.class放在相同位置。

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

全局类型转换器,必须提供一个xwork-conversion.properties文件。文件必须保存在classes目录下。该资源文件名格式如下:

复合类型=对应的类型转换器

复合类型:指定需要完成类型转换的复合类

对应的类型转换器:指定所指定类型转换的转换器。

如:注册User类的全局类型转换器为:UserConverter

cn.wjz.bean.User = cn.wjz.util.UserConverter

注意:如果局部类型转换和全局类型转换同时存在的话,局部类型转换具有较高的优先级,也就是以局部类型转换器为主。

三.集合类型的类型转换
对于List元素来说,内容如: Element_attributeName=typeName;

对于Map元素来说,

(1)如果表示key的类型,则:Key_attributeName=typeName;

(2)如果表示value的类型,则为:Element_attributeName=typeName;

比如,此处没有使用泛型,而是使用了局部类型转换文件:

[java] view plaincopyprint?

  1. Conversion02Action.java

  2. public class Conversion02Action extends ActionSupport {

  3. private List lists;

  4. private Map maps;

  5. public String execute()throws Exception{

  6. System.out.println(((Person)lists.get(0)).getGender());

  7. System.out.println(((Person)lists.get(0)).getSalary());

  8. System.out.println(((Person)maps.get("one")).getGender());

  9. System.out.println(((Person)maps.get("one")).getSalary());

  10. return SUCCESS;

  11. }

  12. public List getLists() {

  13. return lists;

  14. }

  15. public void setLists(List lists) {

  16. this.lists = lists;

  17. }

  18. public Map getMaps() {

  19. return maps;

  20. }

  21. public void setMaps(Map maps) {

  22. this.maps = maps;

  23. }

  24. }


Conversion02Action-conversion.properties

[html] view plaincopyprint?

  1. Element_lists=org.person.Person

  2. Key_maps=java.lang.String

  3. Element_maps=org.person.Person


页面表单:

[html] view plaincopyprint?

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部