基于OGNL的类型转换

简介:

借助于内置的类型转换器,Struts 2可以完成字符串和基本类型之间的类型转换。除此之外,借助于OGNL表达式的支持,Struts 2允许以另一种简单方式将请求参数转换成复合类型。系统的Action类代码片段如下。

程序清单:codes\04\4.1\ognlConvert\WEB-INF\src\org\crazyit\app\domain\LoginAction.java

public class LoginAction implements Action

{

     //User类型属性封装请求参数

     

     

     //省略两个属性的settergetter方法

     

     

     

          //通过user属性的name属性和pass属性来判断控制逻辑

          

               

          

               setTip("转换成功");

               

          

          

          

               setTip("转换失败");

               

          

     

}

从上面Action的粗体字代码可以看出,该Action里包含了一个User类型的属性——这个属性需要进行类型转换,Struts 2框架接收到HTTP请求参数后,需要将这些请求参数封装成User对象。

Struts 2提供的OGNL表达式允许开发者无须任何特殊处理,只需要在定义表单域时使用OGNL表达式来定义表单域的name属性。JSP页面的表单代码如下。

程序清单:codes\04\4.1\ognlConvert\input.jsp

<s:form action="login">

     <!-- 该表单域封装的请求参数名为user.name -->

     <s:textfield name="user.name" label="用户名"/>

     <!-- 该表单域封装的请求参数名为user.pass -->

     <s:textfield name="user.pass" label="密码"/>

     

          <td colspan="2"><s:submit value="转换" theme="simple"/>

          <s:reset value="重填" theme="simple"/></td>

     

</s:form>

上面的表单定义中粗体字代码定义了两个单行文本框,对应两个请求参数,请求参数名并不是普通参数名,而是user.nameuser.pass的形式——这就是OGNL表达式的形式,Struts 2会把user.name参数的值赋值给Action实例的user属性的name属性,并将user.pass参数的值赋值给Action实例的user属性的pass属性。

通过这种方式,Struts 2可以将普通请求参数转换成复合类型对象,但在使用这种方式时有如下几点需要注意:

Ø  因为Struts 2将通过反射来创建一个复合类(User类)的实例,因此系统必须为该复合类提供无参数的构造器。

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

更极端的情况是,我们甚至可以直接生成Collection,或者Map实例。看如下的Action类片段。

程序清单:codes\04\4.1\ognlObjectMap\WEB-INF\src\org\crazyit\app\action\LoginAction.java

public class LoginAction implements Action

{

     //Action类里包含一个Map类型的参数

     //Mapvalue类型为User类型

     

     

     //users属性的settergetter方法

     

     

          

     

     

     

          

     }   

     //省略tip属性的settergetter方法

     

     

     

          //在控制台输出Struts 2封装产生的List对象

          

          //根据Map集合中keyoneUser实例来决定控制逻辑

          

               

          

               setTip("登录成功!");

               

          

          

          

               setTip("登录失败!!");

               

          

     

}

上面Action的粗体字代码部分定义了一个users属性,该属性的类型为Map<String , User>,只要我们在定义表单域的name属性时使用OGNL表达式语法,Struts 2一样可以将请求参数直接封装成这种users属性。例如如下表单定义代码。

程序清单:codes\04\4.1\ognlObjectMap\input.jsp

<s:form action="login">

     <s:textfield name="users['one'].name" label="one个用户名"/>

     <s:textfield name="users['one'].pass" label="one个密码"/>

     <s:textfield name="users['two'].name" label="two个用户名"/>

     <s:textfield name="users['two'].pass" label="two个密码"/>

     

          <td colspan="2"><s:submit value="转换" theme="simple"/>

          <s:reset value="重填" theme="simple"/></td>

     

</s:form>

上面的粗体字代码示范了如何利用OGNL表达式来定义表单域的name属性:将表单域的name属性设置为“Action属性名['key'].属性名”的形式,其中“Action属性名”是Action类里包含的Map类型属性,后一个属性名则是Map对象里复合类型对象的属性名。通过这种方式,Struts 2可以将HTTP请求参数转换成Map属性。

类似地,如果我们需要访问ActionMap类型的属性,也可以使用OGNL表达式,如下面的代码所示:

keyone的用户名为:<s:property value="users['one'].name"/><br/>

keyone的密码为:<s:property value="users['one'].pass"/><br/>

keytwo的用户名为:<s:property value="users['two'].name"/><br/>

keytwo的密码为:<s:property value="users['two'].pass"/><br/>

如果把LoginAction中的users属性改为List<User>,也就是如果需要Struts 2将用户请求参数封装成List属性,一样可以利用OGNL表达式做到——我们通过索引来指定要将请求参数转换成List的哪个元素。下面的JSP页面里的表单元素的name属性可实现将HTTP请求参数转换成List属性。

程序清单:codes\04\4.1\ognlObjectList\input.jsp

<s:form action="login">

     <s:textfield name="users[0].name" label="第一个用户名"/>

     <s:textfield name="users[0].pass" label="第一个密码"/>

     <s:textfield name="users[1].name" label="第二个用户名"/>

     <s:textfield name="users[1].pass" label="第二个密码"/>

     

          <td colspan="2"><s:submit value="转换" theme="simple"/>

          <s:reset value="重填" theme="simple"/></td>

     

</s:form>

上面的JSP页面中定义表单域时指定第一个文本域的nameusers[0].nameStruts 2将会把该文本域所代表的请求参数转换成 users集合第一个元素的name属性。

类似地,如果想输出ActionList属性里各集合元素的属性值,则可通过在集合属性后增加索引来访问,如下面的代码片段所示:

第一个User实例的用户名为:<s:property value="users[0].name"/><br/>

第一个User实例的密码为:<s:property value="users[0].pass"/><br/>

第二个User实例的用户名为:<s:property value="users[1].name"/><br/>

第二个User实例的密码为:<s:property value="users[1].pass"/><br/>

 


 

本文转自fkJava李刚 51CTO博客,原文链接:http://blog.51cto.com/javaligang/871603 ,如需转载请自行联系原作者

相关文章
|
5月前
|
C++
c++类型转换
c++类型转换
76 1
|
5月前
|
安全 编译器 程序员
【C++】—— C++的类型转换
【C++】—— C++的类型转换
|
编译器 C++
【C++】类型转换
【C++】类型转换
63 0
|
存储 安全 编译器
(强制)类型转换方法
(强制)类型转换方法
101 0
|
存储 人工智能 C#
C# 类型转换
但是当大范围转小范围,或者是高精度转低精度的时候,就要考虑范围和精度的问题了。前提是输入的字符串要能够直接转换成对应类型的值,而且要符合目标的存储范围。上面的两种方法常用于数值之间的转换和字符串转换,我们还可以使用。可以实现更加精确的转换,同时,适用的变量类型也更多。是将一个类型的值手动转换成目标类型的转换方式。如果是其他类型转换成字符串则更加简单,只需要使用。类型的变量,这里面就发生了隐式转换。则是不同变量类型之间的自动转换。即不同变量类型之间的相互转换。除此之外,我们还可以通过。类型的变量也可以存储。
94 0
C# 类型转换
|
JavaScript 编译器 C语言
C++类型转换几种情况
C++类型转换几种情况
C++类型转换几种情况
|
编译器 C语言 C++
C++ 类型转换
C++ 类型转换
145 0
C++ 类型转换
|
C++
09.C++类型转换
(创建于2017/12/31) C++类型转换 static_cast 普遍情况 const_cast 去常量 dynamic_cast 子类类型转为父类类型 reinterpret_cast 函数指针转型,不具备移植性 1.
935 0