关闭

Struts2学习:类型转换篇

标签: strutsstringreferenceactionhashmapinput
3975人阅读 评论(0) 收藏 举报
分类:

框架中常规的类型转换对我们而言是透明的,我们无需关心,一般来说我们所要做的是确保HTMLinput的命名能够在OGNL表达式中使用。在HTML中,并没有数据类型的概念,任何数据都被当做字符串或者字符串数组来传递。Struts2为我们提供了一些内建的类型转换,譬如说基本类型之间的转换、1984-08-27格式的字符串能够被正确的转换为Date类型等等。但是这些内建的类型转换有时并不能满足我们的需求,比方说,我们希望用户输入”3,32”格式的坐标字符串时,Struts2能帮我们把这个String类型转化成Point类型,这个时候我们就需要自定义一个类型转换器。具体来说,整个过程可以分为两个步骤:

1.定义一个类型转换类,需实现ognl.TypeConverter接口(文档中无具体实例)

2.给需要进行转换的类或属性指定类型转换器

上述第2步需要用到配置文件,根据作用域的不同可以将配置文件分为两种:类级别和全局级别。

1.类级别配置               

假设我是在MyAction这个action中要对它的Point类型的属性point进行转化,那么我就需要创建一个名字为MyAction-conversion.properties文件,内容如下:

point=com.acme.PointConverter

注意,等号右边的内容应该是我们所定义的类型转化器,这里我们只是给出了一个样例,并没有真正创建这个类型转换类。另外局部类型转换配置文件遵循如下的命名规则:ClassName-conversion.properties

2.全局级别配置

classpath的根目录下创建一个xwork-conversion.properties文件,加入如下内容:

com.acme.Point = com.acme.PointConverter

前后两种配置,等候右边的内容是一样的,只是左右稍微不同。类级别时,左边是类中需进行类型转换的属性的名称;全局级别时,左边是需进行类型转化的类型的全名。

一.内建的类型转换支持

XWork能够自动的为我们处理大多数常见的类型转换,它能帮我们把字符串转换为下面的任意一种类型,也能把下面任意一个类型转换为字符串。这些类型如下所示:

      String

      boolean/ Boolean

      char/Character

      int/Integerfloat/Floatlong/Longdouble/Double

      dates----使用当前时区的SHORT格式

      arrays-----假设每个单独的字符串都能转换成数组中元素的类型

      collections-----如果不能确定集合中元素的类型,会默认是String类型,并创建一个新的ArrayList对象

    对数组进行转换时,会顺延至对数组中的每个元素进行转换。和所有其它的类型转换一样,如果转换无法完成需要使用一个标准的类型转换错误报告来表明处理类型转换时发生了问题。

二.创建一个类型转换器

文档中没有给出具体的实例,只是给我们介绍了一个用于编写类型转换的帮助类。这个类是org.apache.struts.action2.util.StrutsTypeConverter,它能帮助我们方便的编写一个类型转换器。这个类提供了两个抽象方法,以便我们将目标类型转换为String或者将String转换为目标类型。这两个方法是convertFromStringconvertToString,关于它们的使用可以参考Struts2自带的API说明文档,很容易理解。下面是文档中给出的片段:

 

public class MyConverter extends StrutsTypeConverter {
 public Object convertFromString(Map context, String[] values, Class toClass){
       //定义如何将字符串转换为目标类型
    }
 public String convertToString(Map context, Object o) {
       //定义如何将目标类型转换为字符串
    }
 }

三.高级类型转换

1.处理null属性访问

如果action上下文中的#CREATE_NULL_OBJECTS被指定为true,那么当OGNL表达式遇到空指针异常时,表达式会暂时停止计算(evaluate),系统会自动尝试创建一个新的对象来解决这个空指针问题。#CREATE_NULL_OBJECTS的值只能够在ParametersInterceptor的执行过程中被指定。处理null属性有如下一些规则:

      当属性被声明为Collection或者List时,返回一个ArrayList对象来赋给空的reference

      当属性声明为Map时,返回一个HashMap对象赋给空的reference

      当属性声明为一个简单带有无参数构造方法的javabean时,调用无参数的构造方法生成这个javabean的实例赋给空的reference

2.对集合(Collection)Map的支持

Struts2框架支持多种方式来发现(discover)集合中元素的类型,这个发现(discover)是通过ObjectTypeDeterminer类来完成的,框架提供了这个类的默认实现。ObjectTypeDeterminer类会查看ClassName-conversion.properties文件来得知Collection或者Map中存放的是什么对象。对Collection而言,比如List,元素是通过Element_xxx格式来指定的,xxx用来指代我们的action或者对象中Collection类型属性的名字。对于Map而言,则需通过Key_xxx Element_xxx来分别指定KeyValue的类型,xxx仍然用来指代我们的action或者对象中Map类型属性的名字。尽管Collection_xxx这种格式已经停止使用,但是目前仍然是支持的。下面看一个对Collection支持的例子。

首先创建一个模型beanMyBeanCollection中存放的都是这个类型的对像:

MyBean.java

public class MyBean implements Serializable {
    private Long id;
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return "MyBean{" +
                "id=" + id +
                ", name='" + name + '/'' +
                '}';
    }
}

这个类很简单:一个id用于唯一标识一个对象,一个name属性。

MyBeanAction.java

public class MyBeanAction implements Action {
    private List beanList = new ArrayList();
    private Map beanMap = new HashMap();
    public List getBeanList() {
        return beanList;
    }
    public void setBeanList(List beanList) {
        this.beanList = beanList;
    }
    public Map getBeanMap() {
        return beanMap;
    }
    public void setBeanMap(Map beanMap) {
        this.beanMap = beanMap;
    }
    public String execute() throws Exception {
        return SUCCESS;
    }
}

这个类中有一个Collection类型的属性beanList,它是一个MyBean类型对象的集合。

MyBeanAction-conversion.properties

KeyProperty_beanList=id
Element_beanList=MyBean
CreateIfNull_beanList=true

上面是一个类级别的类型转换配置文件,Element_beanList=Mybean告诉Struts2框架我们这里指定的不是一个类型转换器,而是指定了集合类型的属性beanList包含的是类型为Mybean的对象。至于KeyProperty_beanList=id则是告诉我们beanList中的对象使用它们的id属性来作为identifier,相当于给这个集合加了一个索引,便于我们查找。

通过这样的设置后我们可以在页面上一次性提交若干个Mybean对象,实现批量保存的效果。譬如前台的html页面就可以这样写:

<input type=”text” name=”beanList[0].name”>

<input type=”text” name=”beanList[1].name”>

<input type=”text” name=”beanList[2].name”>

<input type=”text” name=”beanList[3].name”>

这样当我们提交页面到action中后,Struts2框架会自动为我们在beanList集合中放置好了四个Mybean类型的对象,并且名字是我们在页面中输入的值,尤其是当Myben类有很多属性的时候这个功能特别好用,可以方便的实现数据的批量保存。

 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:399850次
    • 积分:5355
    • 等级:
    • 排名:第5229名
    • 原创:117篇
    • 转载:6篇
    • 译文:8篇
    • 评论:159条
    最新评论
    同道中人