4.3 基于OGNL的类型转换

Struts 2内建的类型转换器可以完成基本数据类型、Date与字符串之间的转换,这些都是简单类型之间的转换。除此之外,由于Struts 2内建的OGNL表达式的支持,因此在Struts 2中甚至可以直接将字符串参数转换成复合类型。

如果系统的Action类代码片段如下。

程序清单:codes\04\4.3\ognlToObject\WEB-INF\src\org\crazyit\struts2\action\RegistAction.java

public class RegistAction implements Action
{
    // User类型属性封装请求参数
    private User user;
    private String tip;
    // user的setter和getter方法
    public void setUser(User user)
    {
          this.user = user;
    }
    public User getUser()
    {
          return this.user;
    }
    // 省略tip的setter和getter方法
    ...
    // 处理用户请求的execute方法
    public String execute() throws Exception
    {
          setTip("转换成功");
          return SUCCESS;
    }
}

上面的Action类中包括一个复合类型属性,可以利用OGNL表达式来直接生成User实例。这种方式主要是在指定输入信息的JSP页面中,并不是直接给出user属性对应的表单域,而是将表单域的name属性对应到user属性的属性。

看下面输入页面代码中表单部分的代码片段。

程序清单:codes\04\4.3\ognlToObject\WEB-INF\content\registForm.jsp

<h1>请输入您的注册信息</h1>
<form method="post" action="regist">
    用户名:<input type="text" name="user.name" /><br />
    密&nbsp;&nbsp;码:<input type="password" name="user.pass"><br />
    年&nbsp;&nbsp;龄:<input type="text" name="user.age"><br />
    生&nbsp;&nbsp;日:<input type="text" name="user.birth"><br />
    <input type="submit" value="注册">
</form>

上面的表单包含4 个请求参数:user.name、user.pass、user.age和user.birth,这是一种表达式的写法,系统会把 user.name 参数的值赋给 Action 实例的 user 属性的 name 属性,并将user.pass参数的值赋给Action实例的user属性的pass属性……依此类推。

通过这种方式,一样可以将输入的字符串参数转换成复合类型对象,但在使用这种方式时需要注意如下几点。

因为Struts 2需要直接创建一个复合类(User类)的实例,因此系统必须保证该复合类有无参数的构造器(可由系统提供或程序员主动提供)。

如果希望使用user.name请求参数的形式为Action实例的user属性的name属性赋值,则必须为user属性对应的复合类(User类)提供setName()方法,因为Struts 2是通过调用该方法来为该属性赋值的。当然Action类中还应该包含setUser()方法。

更极端的情况是,我们甚至可以直接生成Collection,或者Map实例。