java值栈_Struts2 中的值栈是什么?

7.1值栈

7.1.1值栈是什么

简单的说:值栈是对应每一个请求对象的轻量级的内存数据中心。

Struts2中一个很激动人心的特性就是引入了值栈,在这里统一管理着数据,供Action、Result、Interceptor等Struts2的其他部分使用,这样一来,数据被集中管理起来而不会凌乱,大大方便了程序编写。

Struts2中关于值栈的另外一个很激动人心的特性就是:大多数情况下,你根本无需关心值栈,你不用管它在哪里,不用管它里面有什么,你只需要去获取自己需要的数据就可以了。也就是说,你可以隐式的使用值栈。

当然,如果编写自定义的Result或拦截器等较复杂功能的时候,还是需要显示访问值栈的,因此,还是需要你掌握值栈的知识。

7.1.2值栈能干什么

简单的说,值栈能够线程安全的为每个请求提供公共的数据存取服务。

当有请求到达的时候,Struts2会为每个请求创建一个新的值栈,也就是说,值栈和请求是一一对应的,不同的请求,值栈也不一样,而值栈封装了一次请求所有需要操作的相关的数据。

正是因为值栈和请求的对应关系,因而值栈能保证线程安全的为每个请求提供公共的数据存取服务。

7.1.3值栈有什么

事实上,到现在为止,我们一直在讲“值栈”,这种说法其实是不够准确的。为什么呢?因为在Struts2中,值栈又有广义和狭义之分:

1:狭义值栈

通常指的是实现com.opensymphony.xwork2.util.ValueStack接口的对象,目前就是com.opensymphony.xwork2.ognl.OgnlValueStack对象。

狭义值栈主要用来存取动态EL(表达式语言)运算需要的值和结果,当然OgnlValueStack对象主要是用来支持OGNL(对象图导航语言)运算的。

狭义值栈里面存放着一些OGNL可以存取访问的数据,典型如:Action的实例,这样就可以通过OGNL来访问Action实例中的属性的值了

OGNL表达式运算的值,可以设置到值栈中,可以主动访问值栈对象,强行设置

OGNL表达式产生的中间变量,比如在后面使用Struts2的标签的时候,使用循环标签,自然会有循环的变量,这些都存放在值栈中

2:广义值栈

通常指的是ActionContext对象,ActionContext是Action运行的上下文,每个ActionContext是一个基本的容器,包含着Action运行需要的数据,比如请求参数、会话等。

ActionContext是线程安全的,每个线程有一个独立的ActionContext,这样你就不用担心值栈中值的线程安全问题了。

ActionContext里面存放有很多的值,典型如:Request的parameters:请求中的参数,要注意这里的数据是从请求对象里面拷贝出来的,因此这里数据的变化是不会影响到请求对象里面的参数的值的

Request的Attribute:请求中的属性,这里其实就是个Map,存放着请求对象的属性数据,这些数据和请求对象的Attribute是连动的

Session的Attribute:会话中的属性,这里其实就是个Map,存放着会话对象的属性数据,这些数据和会话对象的Attribute是连动的

Application的Attribute:应用中的属性,这里其实就是个Map,存放着应用对象的属性数据,这些数据和应用对象的Attribute是连动的

Value stack:也就是狭义值栈,ActionContext以value stack作为被OGNL访问的根,简单点说,OGNL在没有特别指明的情况下,访问的就是value stack里面的数据

attr:在所有的属性范围中获取值,依次搜索page、request、session和application。

前面已经了解到Xwork与Web是无关的,因此Action不用去依赖于任何Web容器,不用和Servlet 的API去交互,但是Action需要能访问到Web应用的数据,不仅仅是取得请求参数的值,往往也需要在Action里直接获取请求或会话的一些数据,对于这些数据,现在都可以通过ActionContext来获取到。

3:关于广义和狭义

你会看到,在ActionContext里面其实是包含着狭义值栈的,正是因为这个原因,再加上ActionContext还包含其他的数据,因此把ActionContext称为广义值栈。

今后在说值栈的时候,没有特别指明的情况下,多数就是指的广义值栈,反正开发的时候都是说从值栈中获取值。当然,有一种情况除外,就是在页面上使用OGNL的时候,没有特殊标识的情况下,默认是从value statck中取值的。

7.1.4ActionContext的基本使用

前面学习了值栈的基本知识,接下来,看看在程序中具体如何使用值栈。

1:如何获取

要获取ActionContext有两个基本的方法,如果在不能获取到ActionInvocation的地方,可以直接使用ActionContext一个静态的getContext方法,就可以访问到当前的ActionContext了,示例如下:

java代码:

ActionContext ctx = ActionContext.getContext();

如果在能获取到ActionInvocation的地方,比如在拦截器里面、自定义的Result里面等,可以通过ActionInvocation来获取到ActionContext,示例如下:

java代码:

ActionContext ctx = actionInvocation.getInvocationContext();

2:获取过后,如何使用

ActionContext主要的功能是用来存放数据的,典型的方法如下:get(String key):根据key从ActionContext当前的存储空间里面获取相应的值

put(String key, Object value):把值存储在ActionContext的存储空间里面

Map getApplication():返回ServletContext中存储的值

Map getSession():返回HttpSession中存储的值

Map getContextMap():返回当前context存储的值

Map getParameters():返回HttpServletRequest对象里面存储的,客户端提交的参数

ValueStack getValueStack():获取OGNL的值栈

对于getXXX的方法,都有对应的setXXX方法,这里就不去赘述了,具体的请参看Struts2的API文档。

3:应用示例

可以参看上一章的两个有用的拦截器这一小节,两个拦截器都使用了ActionContext对象,因此这里就不去赘述了。

7.1.5ValueStack的基本使用

在上一小节中,看到了ValueStack被包含在ActionContext中,ValueStack也是用来存储对象的,但是它主要是通过OGNL表达式来访问,也就是说,在Struts2里面主要是通过标签来访问的。

ValueStack有一个特点,如果访问的值栈里有多个对象,且相同的属性在多个对象中同时出现,则值栈会按照从栈顶到栈底的顺序,寻找第一个匹配的对象。

1:如何获取

直接由ActionContext对象的getValueStack()方法即可获取

2:如何使用

ValueStack主要的功能也是用来存放数据的,典型的方法如下:Object findValue(String expr):根据表达式在value stack中,按照缺省的访问顺序去获取表达式对应的值

void setValue(String expr, Object value):根据表达式,按照缺省的访问顺序,向value stack中设置值

Object peek():获取value stack中的顶层对象,不修改value stack对象

Object pop():获取value stack中的顶层对象,并把这个对象从value stack中移走

void push(Object o):把对象加入到value stack对象中,并设置成为顶层对象

3:应用示例

前面的示例中,欢迎页面显示的帐号,是从登录页面填写并传递到后台的数据,假如现在想要修改在欢迎页面显示的帐号数据,但是前面从登录页面填写并传递到后台的数据不需要变化,那么该怎么实现呢?

先来分析一下,要想修改result页面显示的值,肯定需要在Result处理之前修改这个值,否则等Result处理完成过后再改就没有意义了。因此,可以选用PreResultListener的技术,在里面把值修改好,然后再进行Result处理。

另外一点,在欢迎页面是通过标签来获取帐号的数据并展示的,也就是说值的来源是value stack,因此,在PreResultListener里面要修改的就是value stack里面的值。

好了,清楚该干什么过后,来具体看看示例。

(1)先来实现PreResultListener,在里面修改value stack里面的值,示例如下:

java代码:

publicclassMyPreResultimplementsPreResultListener{

publicvoidbeforeResult(ActionInvocation actionInvocation, String result) {

System.out.println("现在处理Result执行前的功能,result="+result);

actionInvocation.getInvocationContext().getValueStack().setValue("account","被修改了");

}

}

(2)实现了PreResultListener,还需要在运行之前注册,这里选择在Action里面来注册这个监听器,示例如下:

java代码:

publicclassHelloWorldActionextendsActionSupport {

privateString account;

privateString password;

privateString submitFlag;

publicString execute()throwsException {

this.businessExecute();

ActionContext c = ActionContext.getContext();

MyPreResult pr = newMyPreResult();

c.getActionInvocation().addPreResultListener(pr);

return"toWelcome";

}

/**

* 示例方法,表示可以执行业务逻辑处理的方法,

*/

publicvoidbusinessExecute(){

System.out.println("用户输入的参数为==="+"account="+account+",password="+password+",submitFlag="+submitFlag);

}

//属性对应的getter/setter方法,省略了

}

(3)相应的struts.xml就比较简单了,示例如下:

java代码:

/s2impl/welcome.jsp

(4)登录页面没有变动,示例如下:

java代码:

账号:

密码:

(5)再看看欢迎页面,也没有变动,示例如下:

java代码:

欢迎账号为的朋友来访

(6)去运行测试看看,欢迎页面显示出来的就应该是修改过后的值了,如下图所示:

37981096_1.jpg

图7.1  修改result数据的欢迎页面

由于通常情况下,向value stack里面压入值都是由Struts2去完成,而访问value stack多是通过标签中的OGNL表达式,因而直接使用ValueStack的机会并不是很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java try的用法_Java中try、catch的使用方法

Java中有两种处理异常的方式,分别是用throws抛出异常、用try、catch捕获异常。try-catch在Javatry-catch语句的语法格式:try{//代码块}catch(Exception1 e){//抛出异常后所要进行的操作}当try语句当中捕获到异常时,会将异常抛出到catch语句中…

java not a jpeg file_javax.imageio.IIOException: Not a JPEG file: starts with 0x47 0x49

java处理图片时出现异常javax.imageio.IIOException: Not a JPEG file: starts with 0x47 0x49at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)at com.sun…

java if用法_java中if语句的写法

if语句if 语句的语法如下:if(布尔表达式){//如果布尔表达式为true将执行的语句}如果布尔表达式的值为 true,则执行 if 语句中的代码块,否则执行 if 语句块后面的代码。免费视频教程推荐:java视频教程if...else语句if 语句后面可以…

java子类和父类实例_java中父类与子类之间的转换示例

java中父类与子类之间的转换示例有以下三点:示例一父类强制转子类pre class"brush:php;toolbar:false">Father f new Son();Son s (Son)f;//可以创建一个父类的实例,想要强制把父类对象转换成子类的,不行!通俗的想…

java 原子类能做什么_死磕 java原子类之终结篇(面试题)

概览原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程上下文切换。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割…

java对docker_如何在docker中运行java程序

吃鸡游戏创建一个redis docker容器首先,我们先为redis创建一个DockerfileFROM ubuntu:12.10RUN apt-get updateRUN apt-get -y install redis-serverEXPOSE 6379ENTRYPOINT ["/usr/bin/redis-server"]现在你需要通过Dockerfile创建一个镜像,将…

java canvas 画图片_canvas画布——画八卦图

浏览器支持Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持 arc() 方法。注释:Internet Explorer 8 或更早的浏览器不支持 元素。定义和用法arc() 方法创建弧/曲线(用于创建圆或部分圆)。提示:如需通过 arc() 来创建圆,请把起…

java多线程编程—高级主题_Java day20 高级编程【第一章】Java多线程编程

【第一章】Java多线程编程一.进程与线程多个时间段会有多个程序依次执行,但是同一时间点只有一个进程执行线程是在进程基础之上划分的更小的程序单元 ,线程是在进程基础上创建并且使用的,所以线程依赖于进程的支持,但是来讲&#…

java object数组转实体类_详解Java中String JSONObject JSONArray List实体类转换

JSON使用阿里的fastJson为依赖包gradle依赖管理如下:compile group: "com.alibaba", name: "fastjson", version:"1.2.41"1、String转JSONObject前言:String 是JSONObject格式的字符串eg:JSONObject jSONObject JSONObje…

e x泰勒 java_maven project

最近没事了玩一下maven,使用maven管理工程中的依赖包非常的方便。建立maven web工程的时候开始不知道怎么用tomcat来调试,总是使用mave的tomcat插件发布了后来调试,觉得非常的麻烦,网上找了点材料,看看maven web工程不…

java定义说话方法_类定义的基本形式_Java语言程

类定义的基本形式_Java语言程4.2.1 类定义的基本形式前面一节我们已经了解了类和对象的概念,然而在实际编程过程中,该如何定义一个类以及类中的对象呢?在Java语言中,用户自己可以定义一个类,作…

java创建线程几种_java中创建线程有几种方式

详细内容线程的创建方式1、继承Thread类实现多线程2、覆写Runnable()接口实现多线程,而后同样覆写run()。推荐此方式3、使用Callable和Future创建线程相关视频教程推荐:java学习视频实例如下:1、继承Thread类实现多线程/** 继承Thread类创建线…

php自定义中文分词方法,php实现的中文分词类完整实例

本文实例讲述了php实现的中文分词类。分享给大家供大家参考,具体如下:该中文分词类源码使用http://tools.ddpool.cn/code/jb51_php_format进行了格式化处理,便于阅读。具体代码如下:class Segmentation {var $options array(lowe…

手机电脑自适应导航源码php,自适应各终端懒人网址导航源码 v2.0

自适应各终端懒人网址导航源码。V2.0版本是在原1.8版本的基础上修复和增加了些功能。推荐直接使用新版本,舍弃旧版本,后期会继续不定期更新。测试环境:宝塔Nginx -Tengine2.2.3的php5.5mysql先导入数据库文件db/db.sql再修改config.php数据库…

php如何生成本地文档,php如何生成word文件

php生成word文件的方法:需求:甲方爸爸说“我有一个word文件,里面是关于用户信息的表格,你帮我把系统里面所有用户数据都按照这个文件导出来给我“;我当时就不乐意了,啪的一拍桌子站起来,愤愤的回…

php 显示状态,php-fpm status状态配置显示

系统为ubuntu,在usr/etc/sites-enabled/中编辑nginx配置文件server_name demo.com;location ~^/status$ {#auth_basic "status page";#fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;include fastcgi_params;fastcgi_pass unix:/var/…

matlab 动态目录调用程序集,C#中如何动态添加程序集查找目录

C#中如何动态添加程序集查找目录情况如下:现有三个程序集Main.exe, One.dll, Two.dll。其中One.dll引用了Two.dll, 并且One.dll与Two.dll部署在一起, 而Main.exe单独部署。在One.dll中有using Two;namespace One{public SomeType{public void DoSomethin…

matlab 红黑强度图片,matlab图形锐化程序

满意答案gveial5852013.10.31采纳率:50% 等级:12已帮助:11498人help imreadhelp fspecial imfilt帮助稳定中有较多的示例fspecial 函数功能:产生预定义滤波器格式:Hfspecial(type)Hfspecial(gaussian,n,sigma) 高斯…

php基础学哪些,榆林学习php需要哪些基础(PHP是什么)

榆林学习php需要哪些基础,想多学一门知识,陕西PHP培训对我们都是大有裨益的,紧接着就去了解下php代码运行方式有哪些,php常用框架有哪些,php为啥遭到它行鄙视,PHP是什么,php的性质有哪些&#x…

oracle 11gr2 asm安装,OEL6.1下oracle 11gr2 ASM安装

oracle 11gr2下asm与以往不同,是使用grid安装包来完成安装与配置,在11.2.0.3的安装包中,使用第三个安装包,解压以后进行以下配置:1. Asm相关用户及组配置/usr/sbin/groupadd -g 502 oper/usr/sbin/groupadd -g 600 asm…