[关闭]
@liayun 2016-10-03T08:11:42.000000Z 字数 6125 阅读 1271

Struts2框架进阶(五)

Struts2框架学习


这时Struts2框架进阶五,本文将详细讲解OGNL表达式语言。

OGNL表达式语言简介

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2框架使用OGNL作为默认的表达式语言。相对EL表达式,它提供了平时我们需要的一些功能,如:

OGNL中的上下文(Context)

OGNL有一个上下文(Context)的概念,说白了上下文就是一个Map结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图:
插入上下文(Context)的结构示意图
当Struts2接收一个请求时,它迅速创建ActionContext,ValueStack,action对象,然后action被存到ValueStack,所以action的实例变量可以被OGNL访问到。

如何访问上下文(Context)中的对象

访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session。
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
在Struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想象的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用它来存放一组对象的。
记得插入图片
在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止
大家注意:在Struts2中,OGNL表达式需要配合Struts2标签才可以使用。如:

  1. <s:property value="name" />

value属性默认接收的是OGNL表达式。
标准的OGNL会设定一个根对象(root对象)。假设使用标准OGNL表达式来求值(不使用Struts2的OGNL表达式),如果OGNL上下文(OgnlContext Map类型)有两个对象:foo对象,在Ognl Context中名称为foo;bar对象,在Ognl Context中名称为bar,同时foo对象被设置为根对象(root),则利用下面的OGNL表达式求值:

  1. #foo.blah // 返回foo.getBlah()
  2. #bar.blah // 返回bar.getBlah()
  3. blah // 返回foo.getBlah(),因为foo为根对象

记住:访问Ognl Context中的对象需要使用#符号标注命名空间,如#bar,如果要访问的属性属于根对象,则可以省略命名空间,直接访问该属性

访问Struts2中OGNL的根对象——ValueStack(值栈)

由于ValueStack(值栈)是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,则可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:

  1. ${foo } // 获得值栈中某个对象的foo属性 例如:${message }

我们举例来说明这一点。首先在cn.itcast.action包下创建一个Action——PersonListAction.java,该Action类的具体代码如下:

  1. public class PersonListAction {
  2. private String name;
  3. public String getName() {
  4. return name;
  5. }
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. public String execute() {
  10. this.name = "李阿昀";
  11. return "list";
  12. }
  13. }

接下来就在struts.xml配置文件中配置该action。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/itcast" extends="struts-default">
  7. <action name="list" class="cn.itcast.action.PersonListAction">
  8. <result name="list">/WEB-INF/page/personlist.jsp</result>
  9. </action>
  10. </package>
  11. </struts>

顺其自然地,我们要在WEB-INF/page/目录下创建出personlist.jsp页面。

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib uri="/struts-tags" prefix="s"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. ${name }<br/>
  12. </body>
  13. </html>

我们通过浏览器访问http://localhost:8080/struts2_ognl/itcast/list.action该URL地址,结果为:
记得插入图片
我们可能会思考一个问题,为何使用EL表达式能够访问ValueStack中对象的属性呢?
翻阅Struts2的源码,我们就会发现Struts2对HttpServletRequest对象作了进一步的封装,代码如下:

  1. public class StrutsRequestWrapper extends HttpServletRequestWrapper {
  2. public StrutsRequestWrapper(HttpServletRequest req) {
  3. super(req);
  4. }
  5. public Object getAttribute(String s) {
  6. ......
  7. ActionContext ctx = ActionContext.getContext();
  8. Object attribute = super.getAttribute(s); // 先从request范围获取属性值
  9. if (ctx != null) {
  10. if (attribute == null) { // 如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
  11. ......
  12. ValueStack stack = ctx.getValueStack();
  13. attribute = stack.findValue(s);
  14. ......
  15. }
  16. }
  17. return attribute;
  18. }
  19. }

所以,如果用户需要访问值栈中的对象,则可以直接通过EL表达式访问ValueStack(值栈)中对象的属性。

访问Struts2中其他Context中的对象

如果访问其他Context中的对象,由于不是根对象,在访问时,需要加#前缀。

使用ognl表达式创建List/Map集合对象

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。

使用ognl表达式来创建一个List类型集合的对象

我们可使用如下代码直接生成一个List对象:

  1. <s:set var="list" value="{'第一个','第二个','第三个'}" />
  2. <s:iterator value="#list">
  3. <s:property /><br>
  4. </s:iterator>

set标签用于将某个值放入指定范围。

property标签用于输出指定值。如:

  1. <s:set name="name" value="'kk'" />
  2. <s:property value="#name"/>

为了验证这一点,我们在WebRoot根目录下创建一个test.jsp页面,如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib uri="/struts-tags" prefix="s"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>测试页面</title>
  9. </head>
  10. <body>
  11. <!-- 如何使用ognl表达式来创建一个List类型集合的对象 -->
  12. <s:set var="list" value="{'第一个','第二个','第三个'}" />
  13. <!-- #list为ognl表达式,s:iterator标签在迭代集合时有个特点:会把当前迭代的对象放在值栈的栈顶中 -->
  14. <s:iterator value="#list">
  15. <s:property /><br/>
  16. </s:iterator>
  17. </body>
  18. </html>

注意两点:

  1. #list为ognl表达式。
  2. <s:iterator>标签在迭代集合时有个特点:会把当前迭代的对象放在值栈的栈顶中。

这样,我们通过浏览器访问http://localhost:8080/struts2_ognl/test.jsp该URL地址,结果是:
记得插图

使用ognl表达式来创建一个Map类型集合的对象

我们可使用如下代码直接生成一个Map对象:

  1. <s:set var="maps" value="#{'key1':90,'key2':35,'key3':12}" />
  2. <s:iterator value="#maps">
  3. <s:property value="key" />=<s:property value="value" /><br/>
  4. </s:iterator>

为了验证这一点,我们将test.jsp页面的内容修改为:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib uri="/struts-tags" prefix="s"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>测试页面</title>
  9. </head>
  10. <body>
  11. <!-- 如何使用ognl表达式来创建一个Map类型集合的对象 -->
  12. <s:set var="maps" value="#{'key1':90,'key2':35,'key3':12}" />
  13. <!-- #maps为ognl表达式,s:iterator标签在迭代集合时有个特点:会把当前迭代的对象放在值栈的栈顶中,就可以采用ognl表达式直接访问对象的属性 -->
  14. <s:iterator value="#maps">
  15. <s:property value="key" />=<s:property value="value" /><br/>
  16. </s:iterator>
  17. </body>
  18. </html>

这样,我们通过浏览器访问http://localhost:8080/struts2_ognl/test.jsp该URL地址,结果是:
记得插图

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注