Struts2_ognl表达式&操作值栈

电脑杂谈  发布时间:2019-07-24 09:06:44  来源:网络整理

位移运算 还是 移位运算_struts2ognl表达式和运算符_el表达式三元运算 空

ssh框架之struts的ognl表达式语言、onglcontext对象:一、概述:ognl表达式,ognl是(对象图导航语言)的缩写struts2ognl表达式和运算符,它是一个开源项目。ognl是object-graph navigation language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,通过简单一致的表达式语法,可以存取对象的任何属性,调用对象的方法,遍历整个对象的,实现字段类型转化等功能、它使用相同的表达式去存取对象的属性。ognl是object-graph navigation language对象图导航语言的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的,实现字段类型转化等功能。

Struts2框架使用OGNL作为默认的表达式语言,主要用于页面的取值。它类似于EL表达式语言,但比EL语法强大很多。

EL Expression Language 表达式语言, 主要用来获取 JSP页面四个域范围数据 (page、 request、 session、 application )

1. 导入的jar包:
    ognl-xxx.jar : ognl的核心环境
    javassist-xxx.jar : ognl的依赖,提供字节码修改能力。
2. 使用ognl表达式的jsp页面需要导入struts2的标签库
    <%@ taglib prefix="s" uri="/struts-tags"%>
3. 几种基本的使用方式:
    1. Java对象的直接访问 :
        <s:property value="'name'"/><br/>
    
    2. 实例方法调用
        <s:property value="'name'.length()"/><br/>      
    3. 赋值操作或表达式串联
        <s:property value="1+1" /><br/>
    4. 静态方法调用(类的静态方法或静态变量的访问) 不推荐
        语法:@[类全名(包括包路径)]@[方法名|值名]
        例如:<s:property value="@java.lang.Math@max(10,20)"/><br/>
        但是!!!在使用静态方法之前必须在struts.xml中开启静态方法调用功能
        <!-- 开启ognl表达式静态方法调用 -->
        <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    5. OGNL上下文(OGNL Context)和ActionContext的访问。(值栈相关访问-重要)
    6. 集合对象的操作

值栈(ValueStack),是Struts2的数据中转站,其中自动保存了当前Action对象和其他相关对象(包括常用的Web对象的引用,如request等),也可以手动保存自己的数据对象struts2ognl表达式和运算符,同时也可以随时随地将对象从值栈取出或操作(通过OGNL表达式)

了解:值栈的生命周期,和request一样或action,生命周期都一样

在Action动作类中获取值栈对象有两种方式:

@Override
public String execute() throws Exception {
    //目标 :获取值栈对象
    //方式一 : 通过request对象直接获取
    ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
    
    //方式二 : 通过struts2提供的api来获取(底层还是1方式)
    ValueStack valueStack2 = ActionContext.getContext().getValueStack();
    
    //测试是否是同一个对象
    System.out.println(valueStack == valueStack2);
    return NONE;
}

在值栈的内部有两个逻辑部分:


    值栈ValueStack(OgnlValueStack实现类)中有两块区域 :
    一块是CompoundRoot对象栈(也称为Root栈),它实质上是使用List集合来存放对象,存入对象压栈从栈顶往下压。
    一块是OgnlContext上下文栈(也称为Map栈)。
        Map栈中有两个区域,_root用于存放对象栈(Root栈)的引用
        _values实质上使用Map集合键值对的形式存放对象

img12.png

值栈是在请求对象引用了一块存储空间。

struts2ognl表达式和运算符_位移运算 还是 移位运算_el表达式三元运算 空

值栈包括两部分: 对象栈(CompoundRoot,继承List接口)和OGNL上下文栈(OgnlContext,实现Map接口)

10. 一个文件映射对象的映射视图维持着对象的内部引用,直到所有的引用被释放,文件映射对象才能够被关闭。11.注意,虽然createfilemapping会增加文件对象计数,mapviewoffile会增加映射对象的计数(也就是说,在unmapviweoffile之前这两个内核对象就可以被closehandle了),但是如果太早关闭映射对象,其他地方要打开映射对象时会失败(即openfilemapping失败或者createfilemapping的lasterror不是error_already_exists),也就是说,内核通过视图对映射对象的引用,不能被用户模式代码检测到,因此最好还是按传统顺序先unmapviewoffile再closehandle。struts2将ognl上下文设置为struts2中的actioncontext(内部使用的仍然是ognlcontext),并将值栈设为ognl的根对象。

栈的概念:
栈是一种数据结构,它按照先进后出的原则存储数据,即先进入的数据被压入栈底,
最后进入的数据在栈顶,需要读取数据的时候,从栈顶开始弹出数据(即最后一个数据被第一个读出来)。
栈也被成为先进后出表,可进行插入和删除操作,插入称之为进栈(压栈)(push),
删除称之为退栈(pop),允许操作的两端分别称为栈顶(top)和栈底(bottom)。栈底固定,而栈顶浮动。
对于栈就只能每次访问它的栈顶元素,从而可以达到保护栈顶元素以下的其他元素的目的。
@Override
public String execute() throws Exception {
    // 目标 :向root栈和map栈中分别存入数据
    String msg = "我爱java";
    
    // 获取值栈对象
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    
    //向root栈中存值(压栈),匿名,
    valueStack.push(msg);
    //root栈中存值(压栈),有名字
    valueStack.set("msg2", "我爱C++");
    //向Root栈中存值(键值对)
    ActionContext.getContext().put("msg3", "我爱Python");
    return SUCCESS;
}
struts.xml 配置跳转页面 :
    <action name="valueStack2" class="com.itdream.a_valueStack.ValueStack2Action">
            <result>/a_ognl/result.jsp</result>
    </action>
result.jsp : 
<%@ taglib prefix="s" uri="/struts-tags"%>
<!-- 取出存在值栈中的值 -->
<!-- push方法,匿名压入Root栈的数据,第一个被压入 -->
<s:property value="[1].top"/><br/>
<!-- set方法,Struts2帮我们创建一个map集合存储数据压入Root栈的数据,map的key就是数据的名字,通过key取值 -->
<s:property value="msg2"/><br/>
<!-- put方法,放入Map栈中,通过加#号定向到Map栈中找 -->
<!-- 也可以不加#号使用默认查找机制,但这样先从Root栈先找,再到Map栈找key,如果在Root栈找到就找不到Map栈的数据了 -->
<s:property value="#msg3"/>|<s:property value="msg3"/><br/>
<!-- 用来查看值栈的内容 -->
<s:debug/>

img14.png

点击Debug查看值栈的内容:

页面中直接查看值栈的元素的方法。
struts2为我们提供了一个标签:<s :debug/>,只要将其加在页面中即可。

Root栈:

数据从栈顶往下压,push方法直接压入String对象,此时它是栈顶,索引为0
然后使用set方法,创建了一个HashMap存储数据的值,作为对象存入Root栈,此时栈顶是这个HashMap对象,String对象的索引变为1

img15.png

位移运算 还是 移位运算_el表达式三元运算 空_struts2ognl表达式和运算符

Map栈:

put方法,以键值对形式存储数据

img16.png

1. 每次请求都会创建一个ActionContext对象和一个OnglValueStack值栈对象,这时在Root栈中放入了一个textProvider.
2. 紧接着,Struts2将与Servket有关的Response,Request,Session等对象放入到Map栈中,此时Map栈中有Servlet的对象引用.
3. 之后就准备执行Action动作类 ,创建Action动作的代理对象。Action是在执行的时候才进行初始化,初始化完成后,
将Action对象压入Root栈栈顶,并在Map栈的_root中放入一个引用:key - action
到这里,Root栈中有一个textProvider与一个Action对象,Map栈中有Servlet相关的数据以及Action对象的引用,
两个Action是同一个
4. 初始化完成,ActionProxy代理对象在执行时,会先执行,再执行Action,
这个时候,如果有Action实现了ModelDriven接口,模型驱动就将模型对象压入栈顶。
了解原理的目的:
知道值栈的初始化时机,访问action的时候,才创建(这个过程中会创建actionProxy对象,并且同时创建值栈,并且,将一些对象放入值栈。)
值栈初始化之后,里面主要默认有:root栈(textProvider、action类对象、model(user)),map栈(servlet相关对象、action对象一个引用)
哪些对象在栈顶!因为后面我们从值栈取值,都从栈顶往下取。所以,一定要知道哪个对象在栈上面。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-115359-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 李攀峰
      李攀峰

      况且国内形式也需要一场外部战争来提高国民的凝聚力

    • 王芳芳
      王芳芳

      而且这次派出的052D也是旧军舰了

    热点图片
    拼命载入中...