OGNL表达式,值栈(ValueStack),类型转换

OGNL表达式,值栈(ValueStack),类型转换

1. 什么是OGNL?

l  全称是Object Graphic Navigation Language,对象图导航语言

它是一种强大的表达式语言,可以通过简单一致的表达式语法来读取和设置Java对象的属性值、调用对象的方法、遍历整个对象的结果图、实现字段类型转换等功能,它是一个开源项目。

l  OGNL表达式的计算是围绕OGNL上下文来进行的

l  OGNL上下文实际就是个Map对象,由ognl.OgnlContext类(实现了java.util.Map接口)

l  OGNL上下文包含多个JavaBean对象,其中包含一个特殊对象,称为根对象(root)

l  在写表达式时,若没指定使用上下文中的某个对象,则根对象作为表达式所依据的对象

l  在写表达式时,访问根对象的属性property就直接书写,否则需要使用#key作为前缀,如:#javabean.property

l  OGNL表达式中的属性(property)是JavaBean的属性(setter/getter),而不是类中的实例变量;在访问JavaBean属性实质就是调用相关的getter方法

2. OGNL支持的常量类型如下

l  字符串常量:使用单引号或双引号括起来的字符串,如:"Hello World! “,‘Hello'

若使用单个字符作为字符串常量,则需要使用双引号括起来如: “H"

l  字符常量:使用单引号括起来的单个字符,不能使用双引号,如:‘H'

l  数值常量: 除Java中的int、long、float和double外,还可以使用b或B后缀指定BigDecimal常量:使用h或H后缀指定BigInteger常量

如:12(int常量),12l(long常量),12.34f(float常量),12.34(double常量),12b(BigDecimal常       量),12h(BigInteger常量)

l  布尔常量:true和false

l  null常量

3. OGNL特有的操作符

l  逗号(,):用于分隔两个或多个独立的表达式,整个表达式是最后一个表达式的值

l  大括号({ }):用于创建列表,创建时将元素使用大括号括起来,元素之间使用逗号分隔。      例如:{"zhangsan","lisi","wangwu"}

l  in和not in:用于判断一个值是否在集合中

4. 创建Map

语法:{"key1":"value1","key2":"value2","key3":"value3"}

例如:{"one":"zhangsan","two":"lisi","three":"lisi"}

可以创建指定的Map类型,例如

#@java.util.LinkedHashMap{"one":"zhangsan","two":"lisi","three":"lisi"}

Map对象通过key来进行访问

例如:map[“one”]或者map.one或者

{"one":"zhangsan","two":"lisi","three":"lisi"}[‘one']

5. 集合的伪属性

OGNL为了简化对Java集合API的方法调用,OGNL提供了一些伪属性,可以按照属性的

方式来访问集合中的方法。

List,Set,Map

size,isEmpty

List.size,set.isEmpty

list.size()、set.isEmpty()

List

iterator

list.iterator

list.iterator()

Map

keys、values

Map.keys,map.values

map.keySet()、map.values()

Set

iterator

set.iterator

set.iterator()

Iterator

next、hasNext

Iter.next,iter.hasNext

iter.next()、iter.hasNext()

Enumeration

Next,hasNext,

nextElement,

hasMoreElements

Enum.next,

enum.hasNext

enum.nextElement()

enum.hasMoreElements()











6.投影

OGNL提供了一种简单方式在一个集合上对每个元素调用相同的方法,并将其结果保存为一个新的集合

例如:

persons是一个包含了person对象的列表,#persons.{name}将返回所有人的名字

投影期间可以使用#this表示当前元素的引用

objects.{ #this instanceof java.lang.String ? #this: #this.toString() }

表示将对象列表中的元素作为字符串值产生一个新的元素列表

7.选择

OGNL提供了一种简单的方式来使用表达式从集合中选择某些元素,并将其结果保存到新的集合中

l  #persons.{?#this.age> 20}

persons表示包含了person对象的列表,返回年龄大于20的所有用户

l  #persons.{?#this.age> 20}[0]

表示返回年龄大于20的所有用户中的第一个用户

**** 需要注意防止发生ArrayIndexOutOfBoundsException异常

u  ?:表示选取匹配逻辑的所有元素

例如,#persons.{?#this.age > 20}

persons表示包含了person对象的列表,返回年龄大于20的所有用户

u  ^:表示选取匹配选择逻辑的第一个元素

例如, #persons.{^#this.age > 20}

persons表示包含了person对象的列表,返回年龄大于20的所有用户中的第一个

u  $:表示选取匹配选择逻辑的最后一个元素

例如, #persons.{$#this.age > 20}

persons表示包含了person对象的列表,返回年龄大于20的所有用户中的最后一个

8. lambda表达式

OGNL提供了一个简化的lambda表达式语法,定义lambda表达式的语法是:[...],其中lambda表达式只能使用一个参数,该参数可以通过#this来进行引用。OGNL将lambda表达式看做是常量

例如,声明一个计算递归的函数,并调用它

#fact = :[#this<=1?1:#this*#fact(#this-1)] ,#fact(30H)

#this表示表达式的参数

初始值为30H,其中H表示BigInteger,每次调用递归表达式都将参数减1

9. 值栈(ValueStack)

l  Struts2将OGNL上下文设置为Struts2中的ActionContext,并将值栈作为OGNL的根对象

l  值栈类似于正常的栈,遵循后进先出的栈特点

l  可以在值栈中存入、删除和查询对象,它是Struts2的核心

l  值栈是通过接口(com.opensymphony.xwork2.util.ValueStack)来定义,对应的实现类是com.opensymphony.xwork2.ognl.OgnlValueStack

l  ActionContext对象中还放置了其他对象,包括表示application、session和request的Map对象。这些对象共存于ActionContext中,靠在值栈(OGNL根对象)的旁边

l  访问值栈

1)    OGNL上下文中的值栈对象可以直接访问,但引用上下文中其他对象需要使用井号(#)来标记

2)    在Struts2中,可以自动从栈顶到栈底查找栈内所有的对象,直到查找到一个具有指定查找属性的对象,即,值栈中的任意对象都可以直接访问,而不需要使用井号(#)例如:有Person和Student对象,都具有name属性,先往栈里存入Person对象,再存入Student对象, Student对象位于栈顶,那对于表达式name,则表示访问Student中的name属性,因为Student位于栈顶,先找到Student对象

3)     



10. [N]语法

l  若需要访问Person对象的name属性,可以使用[N].xxx语法来指定从哪个位值向下开始查找对象的属性;其中,N表示从0开始的整数,它表示从栈中第N个位值开始查询具有xxx属性的对象

例如,表达式[1].name:表示从值栈中索引为1的位值开始查找,查找具有name      属性的对象,并将name输出

11. top关键字


l  在Struts2中,top关键字用于获取栈顶的对象

l  [0].top:表示访问Object0对象

l  [1].top:表示访问Object1对象

l  [2].top.name:表示访问Object2对象的name属性

12. 访问静态成员

l  除了使用标准的OGNL表达式访问静态字段和属性外,Struts2还允许使用“vs”前缀来调用保存在栈中的对象和静态字段和静态方法,而且不需要指定完整的类名

例如:    @vs@someProperty

@vs@someMethod()

@vs2@someProperty

@vs2@someMethod()

l  说明:    其中vs表示“value stack”

直接使用vs表示栈顶的对象

若vs后面若有数字,则表示将使用栈中指定位值处的对象的类

13. 值栈中的Action实例

l  Struts2框架总是把Action实例放置在栈顶;由于Action在值栈中,而值栈又是OGNL的根,所以在引用Action属性时可以省略“#”标记

例如:<s:property value=“xxx"/>

表示输出栈顶的Action实例的xxx属性,但访问其他对象时,需要使用“#”标记

14. Struts2中的命名对象

Struts2中还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,访问这些对象需要使用“#”标记,这些对象都是Map类型

l  命名对象有以下几类

1)    parameters

2)    request

3)    session

4)    application

5)    attr

l  parameters

用于访问请求参数。例如,#parameters[‘pid’]或parameters.pid,相当于调用    HttpRequestServlet对象的getParameter()方法

l  request

用于访问请求属性。例如,#request[‘user’]或#request.‘user’,相当于调用       HttpRequestServlet对象的getAttribute()方法

l  session

用于访问session属性。例如, #session[‘user’]或#session.‘user’,相当于调用     HttpSession 对象的getAttribute()方法

l  application

用于访问application属性。例如, #application[‘user’]或#application.‘user’,相       当于调用ServletContext对象的getAttribute()方法

l  attr

如果PageContext可用,则访问PageContext,否则将依次搜索request、session  和    application,例如,若PageContext对象不可用,#attr[‘user’]或#attr.‘user’       将依次搜索request、session和application对象

14. 与JSP的冲突

在JSP2.1规范中,井号#已经被JSP中的EL表达式语言所使用

对于某些使用OGNL#操作符的应用程序,会出现一些问题,为了避免该问题的出现,通常在web.xml文件中添加代码,禁用JSP中EL表达式的使用

如下所示

15. 类型转换

l  Java是强类型语言,而MVC框架从用户接受过来的数据均是字符串,那么MVC框架就需要将请求的字符串转换成相应的数据类型

l  Struts2提供了非常强大的类型转换支持

l  Struts2类型转换机制的基础是OGNL表达式

l  可以使用ONGL表达式来命名参数

例如,Action类有user属性(类型为User,并有相应的setter和getter方法),那在  表单页面相应的使用OGNL表达式命名,如user.name、user.age等

16. 对集合的支持

l  在Action中,将相关属性的泛型取消

在对应的Action目录下创建名为<Action类>-conversion.properties的文件

l  在该文件下指定集合元素的数据类型

1)    如果集合是java.util.List,格式为:Element_xxx=复合类型

其中Element是固定的,xxx表示Action中属性的集合属性名,复合类型是集合元素 类型的完全限定名


2)    如果集合是java.util.Map,格式为:Key_xxx=复合类型

其中Key是固定的,xxx表示Action中属性的集合属性名,复合类型是集合元素类型  的完全限定名

  

3) Set集合并不维护元素加入的顺序,也不能通过索引来访问元素

在Struts2提供了使用JavaBean对象的属性来索引集合元素方式,通过元素属性值     来唯一获取Set集合中的元素

用于索引集合元素的属性在<Action类名>-conversion.properties文件中通过    KeyProperty_xxx=yyy来指定

其中,xxx表示集合类型的属性,yyy表示是集合元素(即JavaBean对象)的属性名

  

说明:在BookSetAction类中必须要实例化books属性

第2行,指定集合对象

第3行,表示引用的集合元素为null时,框架会自动实例化该对象

17.自定义类型转换:

l  实现TypeConverter接口

l  继承自DefaultTypeConverter类  ****

l  继承自StrutsTypeConverter类 *****

l  convertValue(Mapcontext,Object value,Class toType)方法

l  context:表示OGNL上下文的Map对象

l  value:表示需要转换的对象

l  toType:表示需要转换的目标类型

l  配置自定义转换器

l  应用于全局范围的类型转换器

l  通常在WEB-INF/classes目录下创建xwork-conversion.properties文件,并提供相应的属性定义。其中,属性是要转换的类的名称,属性值是类型转换器的名称

    例如:java.util.Date=xx.xx.XxxConverter

l  应用与特定类的转换器

配置针对某个特定类的类型转换器,方法是在类所在的包中创建       <ClassName>-conversion.properties文件,并提供一个属性定义,等号左边是要    转换的类的属性名,右侧是类型转换器的类名称


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值