一、OGNL表达式语言
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。
 
相对EL表达式,它提供了平时我们需要的一些功能,如:
①支持对象方法调用,如xxx.sayHello();
②支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format('foo %s', 'bar')或@cn.itcast.Constant@APP_NAME;
③操作集合对象。
Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图

Struts 2中的OGNL Context实现者为ActionContext,它结构示意图如下:
当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
 
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
 
在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象
                   |--request  
                   |--application  
context ------|--OgnlValueStack root变量[action, OgnlUtil, ... ]  
                   |--session  
                   |--attr  
                   |--parameters
 
在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顺序访问其属性。
 
为何使用EL表达式能够访问valueStack中对象的属性
原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
public class StrutsRequestWrapper extends HttpServletRequestWrapper {
public StrutsRequestWrapper(HttpServletRequest req) {
super(req);
}
public Object getAttribute(String s) {
......
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);//先从request范围获取属性值
if (ctx != null) {
if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
......
ValueStack stack = ctx.getValueStack();
attribute = stack.findValue(s);
......
}
}
return attribute;
}
}
采用OGNL表达式创建List/Map集合对象
如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。
使用如下代码直接生成一个List对象:
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iterator value="#list" id="n">
<s:property value="n"/><br>
</s:iterator>
生成一个Map对象:

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<s:iterator value="#foobar" >
<s:property value="key"/>=<s:property value="value"/><br>
</s:iterator
Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。如果没有设置该属性,则默认放置在OGNL Context中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。

采用OGNL表达式判断对象是否存在于集合中
对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如下所示。

in表达式:

<s:if test="'foo' in {'foo','bar'}">

</s:if>
<s:else>
不在
</s:else>
not in表达式:
<s:if test="'foo' not in {'foo','bar'}">
不在
</s:if>
<s:else>

</s:else>
OGNL表达式的投影功能
除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
?:获得所有符合逻辑的元素。
^:获得符合逻辑的第一个元素。
$:获得符合逻辑的最后一个元素。
例如代码:

<s:iterator value="books.{?#this.price > 35}">
<s:property value="title" /> - $<s:property value="price" /><br>
</s:iterator>
在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。

public class BookAction extends ActionSupport {
private List<Book> books;
....
@Override
public String execute() {
books = new LinkedList<Book>();
books.add(new Book("A735619678", "spring", 67));
books.add(new Book("B435555322", "ejb3.0",15));
}
}

 示例代码:

book.java

package com.dzq.domain;

public class Book {
private int bookid;
private String name;
private int price; public int getBookid() {
return bookid;
} public void setBookid(int bookid) {
this.bookid = bookid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getPrice() {
return price;
} public void setPrice(int price) {
this.price = price;
} public Book(int bookid, String name, int price) {
this.bookid = bookid;
this.name = name;
this.price = price;
} }

PersonListAction.java

package com.dzq.action;

import java.util.*;

import com.dzq.domain.Book;

public class PersonListAction {
private String name;
private List<Book> books; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public List<Book> getBooks() {
return books;
} public void setBooks(List<Book> books) {
this.books = books;
} public String execute(){
books=new ArrayList<Book>();
books.add(new Book(1, "黑客与画家", 23));
books.add(new Book(2, "傲慢与偏见", 35));
books.add(new Book(3, "春娇与志明", 45));
name="小明";
return "list";
}
}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"> <struts>
<package name="dzq" namespace="/dzq" extends="struts-default">
<action name="list" class="com.dzq.action.PersonListAction">
<result name="list">/WEB-INF/page/personlist.jsp</result>
</action>
</package>
</struts>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setAttribute("user", "xiaoduc");
request.getSession().setAttribute("user", "hello");
%>
<%@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>Insert title here</title>
</head>
<body>
<s:property value="#request.user"/><br>
<s:property value="#session.user"/><br> <s:set var="list" value="{'第一个','第二个','第三个'}" />
<s:iterator value="#list">
<s:property/><br>
</s:iterator>
<s:set var="maps" value="#{'key1':90,'key2':35,'key3':40 }" />
<s:iterator value="#maps">
<s:property value="key" />= <s:property value="value"/><br>
</s:iterator> <s:if test="'foo' in {'foo','value'}">

</s:if>
<s:else>
不在
</s:else> </body>
</html>

personlist.jsp

<%@ 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>Insert title here</title>
</head>
<body>
<s:property value="name"/>
${name }<br>
<s:iterator value="books.{?#this.price>30}" >
书名:<s:property value="name"/><br>
价格:<s:property value="price"/><br>
<hr>
</s:iterator>
</body>
</html>

20160502-struts2入门--ognl表达式的更多相关文章

  1. struts2简单入门-OGNL表达式

    什么是OGNL表达式 Object-Graph Navigation Language的缩写. 可以遍历整个对象结构图,实现对象类型转换等功能的表达式. OGNL实际上是个Map集合,有一个上下文根对 ...

  2. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  3. 初窥struts2(二)OGNL表达式

    Struts2总结 Struts2完整的处理流程: 1  客户端发送请求,交给struts2控制器(StrutsPrepareAndExecuteFilter). 2  Filter控制器进行请求过滤 ...

  4. struts2 与 OGNL 表达式,jsp中 利用ognl 在valuestack中取值

    在Struts2中,一个请求在终于到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以Action对象是 ...

  5. Struts2之OGNL表达式

    OGNL(Object-Graph Navigation Language的简称),对象图导航语言,它是一门表达式语言,除了用来设置和获取Java对象的属性之外,另外提供诸如集合的投影和过滤以及lam ...

  6. struts2(四) ognl表达式、值栈、actionContext之间的关系

    今天来说说ognl表达式在struts2中的运用. --wh 一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任 ...

  7. Struts2之 OGNL表达式和值栈

    技术分析之OGNL表达式概述(了解)        1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写        * 所谓对象图,即以任意 ...

  8. struts2:OGNL表达式,遍历List、Map集合;投影的使用

    OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存 ...

  9. struts2:OGNL表达式之#、%、$符号运用

    1. OGNL表达达符号"#" 1.1 #用于访问OGNL上下文和Action上下文,#相当于ActionContext.getContext() 注意:当系统创建了Action实 ...

随机推荐

  1. Gym 100827G Number Game (博弈)

    Number Game Alice and Bob are playing a game on a line of N squares. The line is initially populated ...

  2. [C++]Microsoft Visual Studio (VS)2010 常用快捷键大全

    VAssistX快捷键 Ctrll+Shift+S   快速查找函数位置  VAssistX提供 Shift+Alt+O     快速查找打开单元  VAssistX提供 Alt+O         ...

  3. soliworks三维机柜布局(二)创建设备位置

    首先声明对三维机柜布局来说,此步骤不是必须的.(创建solidworks装配体文件时,若是创建了位置就可以选择是否为每个位置创建一个装配体,没有创建位置的话只能选择创建整个工程的装配体文件) 在菜单栏 ...

  4. hdoj 2099 整除的尾数

    整除的尾数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. oracle表数据误删还原

    首先,找到数据删除前的一个时间点. select timestamp_to_scn(to_timestamp('2013-10-12 8:30:00', 'YYYY-MM-DD HH24:MI:SS' ...

  6. Android项目实战--手机卫士24--程序锁的实现以及逻辑

    昨天我们已经把程序全部读取出来,显示到界面上了,那今天,我们就来讲一下那个程序锁的实现啦.其实也很简单啦,我们主要就是把用户要锁定的程序放到一个表里面,然后就监听手机里面的任务栈,如果发现任务栈里面出 ...

  7. 关于local storage 和 session storage以及cookie 区别简析

    session storage 和local storage 都是存储在客户端的浏览器内: 一:关于COOKIE 的缺陷 * Cookie的问题 * 数据存储都是以明文(未加密)方式进行存储 * 安全 ...

  8. 常用SQL代码段

    代码使用时须测试. --聚合函数 use pubs go select avg(distinct price) --算平均数 from titles where type='business' go ...

  9. java基础理论知识的一些总结

    在学习Java初期,由于我们是刚开始接触Java,我们不仅需要牢牢掌握Java的基础理论知识,来为我们后面对Java更深层次的学习打好基础,而且我们需要养成编程人的思想习惯.来我们一起来探索Java基 ...

  10. The Sorrows of Young Werther

    The Sorrows of Young Werther J.W. von Goethe Thomas Carlyle and R.D. Boylan Edited by Nathen Haskell ...