博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SSH学习-valueStack和OGNL表达式的使用
阅读量:4624 次
发布时间:2019-06-09

本文共 4469 字,大约阅读时间需要 14 分钟。

Struts2的学习过程中,提到了valueStack和OGNL表达式,这两个是Struts2框架下的概念,这里参考老师授课和博客,进行简单记录和整理,后续有其他理解再添加上去。

概念介绍

(1)valueStack

valueStack是值栈,是Struts2中用户共享数据的一种数据结构,其包含两个区域。

Contents区域

一个是Contents为栈结构(先进后出),也有博客称之为Root区域,主要是一个ArrayList,里面一般放置对象,获取这个区域的数据不需要加#。

浏览器发送一个action请求到服务端filter,会在服务端创建一个action对象和valueStack,将请求所带的数据属性,在contents区域保存,默认值为数据类型初始值,如String类型属性为null,int类型为0,保存到contents区域,当action对象执行使用时,将调用拦截器,将请求中的数据取出来,初始化content区域的属性值,再将contents区域所保存的属性值,赋值给action对象的属性。当action请求结束返回字符串给result后,valueStack将销毁,这就是valueStack的生命周期。

Context区域

另外一个是Context为Map结构,里面放置的是web开发常用的对象数据引用,获取里面的数据需要加#对象名.属性名。常见的几种对象数据引用有(可以通过OGNL表达式的debug标签获取具体内容):

1. Request

2. Session

3. Application

4. Parameters

5. attr

JSP访问方式

1. Contents区域使用OGNL表达式,EL表达式

2. Context区域使用#Key的方式访问对应Value

(2)OGNL表达式

OGNL(Object-Graph Navigation Language),对象图导航语言,OGNL被Struts2整合后将变成它的一种标签,可以在JSP中使用,获取Contents区域的数值。此外它还有其他的强大功能,这里不做详细深究,其他可以参考文末博客。

(3)生命周期

当请求进入服务器端的filter,将创建valueStack对象,当请求结束,valueStack对象将被销毁。

案例测试

案例发送一个action请求到服务端,服务端action请求里有若干属性,在具体的执行方法里,采用两种方式获取valueStack,并往其中一个加入一条对象数据。在JSP页面使用OGNL表达式和EL表达式获取数据进行查看。

(1)struts.xml中的配置

/WEB-INF/msg.jsp

(2)将push到valueStack栈顶的对象所属类,其中包含message属性。

package Entity;/** * 实体类,用于测试valueStack * @author yangchaolin */public class Person {        private int id;    private String name;    private String message;//action请求也将有一个同名的属性message        //创建无参数构造方法    public Person() {        super();    }    //创建有参数构造方法    public Person(int id, String name, String message) {        super();        this.id = id;        this.name = name;        this.message = message;    }...省略get set方法}

(3)action请求处理类,其中也包含一个message属性,跟action中的属性同名同类型。另外session中以key为name也放入了一条数据,其中Person对象中也有属性name。

package Controller;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.util.ValueStack;import Entity.Person;/** * 控制器类 * @author yangchaolin */@Controller@Scope("prototype")public class testValueStack {        private String message;//Person实体类也有同名的属性message    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }        //具体实现方法    public String doValueStack() {                //给属性赋值        message="我是action请求中的message";        //创建person对象        Person p=new Person(1,"我是Person对象中的name","我是Person对象中的message");        //将person对象添加到valueStack中        //action执行的所需的对象保存在ActionContext,如参数,session等                //第一种获取valueStack的方式,根据ActionContext获得        ActionContext ctx=ActionContext.getContext();        ValueStack stack=ctx.getValueStack();        stack.push(p);        //第二种获取valueStack的方式,根据request对象获得        HttpServletRequest request=ServletActionContext.getRequest();        //key为struts.valueStack        ValueStack stack_compare=(ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);        System.out.println("两种获取得到的valueStack相同吗?"+(stack==stack_compare));                //session中也保存一条数据        ctx.getSession().put("name", "我是Session中的name");                return "success";    }}

(4)JSP页面,引入了Struts2的标签库,这样就可以使用OGNL表达式,EL表达式可以直接使用。

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
测试valueStack

使用OGNL表达式

使用EL表达式

${message}
${name}

输出valueStack中的数据,使用debug标签

测试结果

(1)OGNL表达式和EL表达式获取值结果

 从测试结果可以看出来OGNL和EL表达式都可以从Contents区域获取数据,其中message都是Person对象中的message,而不是action对象中的message,是因为action中的message先存到了栈里面,使用表达式取值时是从栈顶往下扫描的,因此先扫描到了Person对象中的message后不再往下扫描,所以的两个表达式获取的都是Person对象中的。而使用EL表达式获取的也是Person对象中,而不是session中的,说明session中的值需要使用#Key的方式获取。

此外两种获取valueStack的方式表明,两者获取的valueStack是一样的。

 (2)debug标签获取Contents和Context中的内容

从结果可以直观的看到数据存储的地方,进而加强对valueStack和OGNL表达式的理解。可以看出session中的name,保存在了Context区域,只能通过#key的方式获取值。而message保存也是先保存了action中的message,后面执行了action中方法后,将Person对象push到栈顶后,才出现第二个message。如果要获取第二个message,需要在JSP中使用[1].message来得到。

 结论

(1)valueStack是封装了action请求中数据的一种特殊数据结构,其中包含Contents区域和Context区域。

(2)获取Contents区域需使用OGNL表达式或EL表达式,获取Context区域数据使用#Key方式

(3)valueStack当action请求结束后将消失。

 

参考博文:

转载于:https://www.cnblogs.com/youngchaolin/p/10879348.html

你可能感兴趣的文章
PHP中获取当前页面的完整URL
查看>>
Chapter 4 Syntax Analysis
查看>>
vi/vim使用
查看>>
讨论Spring整合Mybatis时一级缓存失效得问题
查看>>
Maven私服配置Setting和Pom文件
查看>>
Linux搭建Nexus3.X构建maven私服
查看>>
NPOI 操作Excel
查看>>
MySql【Error笔记】
查看>>
vue入门
查看>>
JS线程Web worker
查看>>
Flex的动画效果与变换!(三)(完)
查看>>
mysql常见错误码
查看>>
Openresty 与 Tengine
查看>>
使用XV-11激光雷达做hector_slam
查看>>
布局技巧4:使用ViewStub
查看>>
学习记事
查看>>
java 子类重写父类的方法应注意的问题
查看>>
[LevelDB] LevelDB理论基础
查看>>
【codecombat】 试玩全攻略 第一关kithguard地牢
查看>>
【DP】 POJ 1191 棋盘分割 记忆化搜索
查看>>