关于Struts2中的值栈与OGNL表达式

简介:

1.1.1    OGNL概述:

Object Graphic Navigation Language(对象图导航语言)的缩写

* EL     :OGNL比EL功能强大很多倍.

它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

OGNL相对其它表达式语言具有下面几大优势:

   1、支持对象方法调用,如xxx.doSomeSpecial();

   2、支持类静态的方法调用和值访问,表达式的格式:

      @[类全名(包括包路径)]@[方法名 |  值名],例如:

             @java.lang.String@format('foo %s', 'bar')

             或@tutorial.MyConstant@APP_NAME;

      设置 struts.ognl.allowStaticMethodAccess=true

   3、访问OGNL上下文(OGNL context)和ActionContext;

   4、支持赋值操作和表达式串联,如price=100, discount=0.8,

        calculatePrice(),这个表达式会返回80;

   5、操作集合对象。

1.1.2    访问类的方法:

<s:property value="'helloworld'.length()"/><br/>

1.1.3    访问类的静态方法:

开启一个常量:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

语法:

@类的全路径@方法名

<s:property value="@java.lang.Math@random()"/><br/>

<s:property value="@java.lang.Math@max(12,15)"/><br/>

<s:property value="@java.lang.String@format('%s,你好','小明')"/><br/>

1.1.4    访问OGNL的上下文:(值栈ValueStack )

什么是值栈?

ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个  ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前   Action 对象和其他相关对象.

Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中,request中

 

结论:

Action何时创建:每次访问的时候创建.Action多实例的.没次访问都会创建一个Action.每个Action中有一个ValueStack对象的引用.

值栈对象ValueStack在request域中有一份.名字struts.valueStack

值栈:Action--->JSP传递值的.

OGNL:获得值栈的数据.

 

值栈的内部结构?

在 ValueStack 对象的内部有两个逻辑部分:

ObjectStack: Struts  把动作和相关对象压入 ObjectStack 中--List

ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中

Struts 会把下面这些映射压入 ContextMap 中

parameters: 该 Map 中包含当前请求的请求参数

request: 该 Map 中包含当前 request 对象中的所有属性

session: 该 Map 中包含当前 session 对象中的所有属性

application:该 Map 中包含当前 application  对象中的所有属性

attr: 该 Map 按如下顺序来检索某个属性: request, session, application

 

值栈ValueStack 和 ActionContext关系? --- 值栈的创建

StrutsPrepareAndExecuteFilter:核心过滤器:(预处理和执行)

核心过滤器 init  和 doFilter 两个方法.服务器启动的时候init就执行了 .每次访问doFilter执行.

Action每次访问的时候会创建.每次请求doFilter都会执行.(Action的创建的代码在doFilter)中.

在doFilter的代码中:

* prepare.createActionContext(request, response);--- 创建了ActionContext对象.

* ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack(); --- 创建了一个ValueStack对象

* ctx = new ActionContext(stack.getContext()); --- 将值栈对象的引用保存到ActionContext中.

***** 所以可以从ActionContext对象中获得到值栈对象.

 

* 将ValueStack存request域中:

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

 

如何获得值栈对象?

两种方式:

// 1.ActionContext对象中有值栈的引用.

    ValueStack valueStack1 = ActionContext.getContext().getValueStack();

   

// 2.从request域中获得值栈对象.

    ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()

            .getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

   

向值栈保存数据?

push(Object obj);    --- 将对象压入到栈顶.

set(String key,Object); --- 创建一个Map集合,将Map集合压入到(root)栈中

 

***** Action对象默认是在栈中的!!!那么在Action中定义的属性呢?

* 对属性提供了相应get方法.获得到属性? -- Action的属性也在栈中.

在页面通过struts2标签 获取值栈内容?

获得root区域值:不需要加#

<s:property value=”name”/>

获得context区域的值:需要加#

<s:property value=”#request.username”/>

通过EL表达式可以访问值栈数据?

底层的代码:StrutsRequestWrapper

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;

    }

 }

1.1.5    OGNL:获得值栈的数据.

#号的用法:

1.获的值栈context中的值

<s:property value="#request.name"/>

<s:property value="#session.name"/>

<s:property value="#application.name"/>

<s:property value="#attr.name"/>

<s:property value="#parameters.name"/>

 

2.投影集合:(对集合中的数据进行过滤)

<h3>遍历整个list集合</h3>

<s:iterator  var="p" value="list">

<s:property value="name"/>---<s:property value="price"/><br/>

<s:property value="#p.name"/>---<s:property value="#p.price"/><br/>

</s:iterator>

 

<h3>过滤要集合的所有的name属性</h3>

<s:iterator value="list.{name}" var="pname">

<s:property value="pname"/>

</s:iterator>

 

<h3>遍历集合中价格大于1500的商品</h3>

<s:iterator value="list.{?#this.price > 1500}">

<s:property value="name"/>---<s:property value="price"/>

</s:iterator>

 

<h3>遍历集合中价格大于1500的商品名称</h3>

<s:iterator value="list.{?#this.price>2000}.{name}" var="pname">

<s:property value="pname"/>

</s:iterator>

 

3.构建一个map集合.

<h3>构建一个List集合</h3>

<!-- 构建一个list集合 -->

<s:iterator value="{'aa','bb','cc','dd'}" var="i" >

<s:property value="i"/>

</s:iterator>

<h3>构建Map集合</h3>

<s:iterator value="#{ 'aa':'name1','bb':'name2','cc':'name3' }">

<s:property value="key"/>---<s:property value="value"/>

</s:iterator>

%号用法:

1.告诉运行环境是一个OGNL表达式:

<% request.setAttribute("name", "张三"); %>

<s:textfield name="name" value="%{#request.name}" label="用户名"/>

 

2.告诉运行环境不是一个OGNL表达式:

<% request.setAttribute("foo", "foo"); %>

<s:property value="%{'#request.foo'}"/>

$号用法:

1.在国际化文件中使用OGNL表达式

itcast.test=${\#request.name}

页面中:

<s:i18n name="message">

<s:text name="itcast.test"></s:text>

</s:i18n>

2.在配置文件XML中使用OGNL表达式

<param name="contentType">${contentType}</param>

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/4093333.html,如需转载请自行联系原作者

相关文章
|
8天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
75 9
|
2天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
5天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
7天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
29 4
|
11天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
24天前
数据结构(栈与列队)
数据结构(栈与列队)
16 1
|
29天前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
63 1
|
25天前
【数据结构】-- 栈和队列
【数据结构】-- 栈和队列
13 0
|
30天前
探索顺序结构:栈的实现方式
探索顺序结构:栈的实现方式
|
30天前
|
存储 C语言
栈和队列题目练习
栈和队列题目练习
16 0
下一篇
无影云桌面