OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
OGNL有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象。
在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。
注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:
<s:property value="name"/>
由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
${foo} //获得值栈中某个对象的foo属性
如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
attr对象:用于按page->request->session->application顺序访问其属性。
下面是OGNL表达式的简单例子:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>OGNL表达式入门</title> </head> <body> <% request.setAttribute("request", "request scope"); request.getSession().setAttribute("session", "session scope"); request.getSession().getServletContext() .setAttribute("application", "application scope"); %> 1.通过ognl表达式获取 属性范围中的值 <br> <s:property value="#request.request" /> <br /> <s:property value="#session.session" /> <br /> <s:property value="#application.application" /> <br /> <br /> 2.通过ognl表达式创建list 集合 ,并且遍历出集合中的值 <br /> <s:set name="list" value="{'eeeee','ddddd','ccccc','bbbbb','aaaaa'}" /> <s:iterator value="#list" var="o"> <!-- ${o }<br/> --> <s:property /> <br /> </s:iterator> <br /> 3.通过ognl表达式创建数组 ,并且遍历出集合中的值 <br /> <s:set name="array" value="new int[] { 1, 2, 3 }" /> <s:iterator value="#array" var="o"> <!-- ${o }<br/> --> <s:property /> <br /> </s:iterator> <br /> 4.通过ognl表达式创建Map集合 ,并且遍历出集合中的值 <br> <s:set name="map" value="#{'1':'eeeee','2':'ddddd','3':'ccccc','4':'bbbbb','5':'aaaaa'}" /> <s:iterator value="#map" var="o"> <!-- ${o.key }->${o.value }<br/> --> <!-- <s:property value="#o.key"/>-><s:property value="#o.value"/><br/> --> <s:property value="key" />-><s:property value="value" /> <br /> </s:iterator> <br /> 5.通过ognl表达式 进行逻辑判断 <br> <s:if test="'aa' in {'aaa','bbb'}"> aa 在集合{'aaa','bbb'}中; </s:if> <s:else> aa 不在集合{'aaa','bbb'}中; </s:else> <br /> <s:if test="#request.request not in #list"> request.request 不在集合list中; </s:if> <s:else> request.request 在集合list中; </s:else> <br /> <br /> 6.通过ognl表达式的投影功能进行数据筛选 <!-- ?:获得所有符合逻辑的元素。 ^:获得符合逻辑的第一个元素。 $:获得符合逻辑的最后一个元素。 --> <br> <s:set name="list" value="{1,2,3,4,5}"></s:set> <s:iterator value="#list.{?#this>2}" var="o"> <!-- #list.{?#this>2}:在list集合迭代的时候,从中筛选出当前迭代对象>2的集合进行显示 --> ${o }<br /> </s:iterator> <br /> 7.通过ognl表达式访问某个类的静态方法和值 <br> <s:property value="@java.lang.Math@floor(32.56)" /> </body> </html>