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 android上传文件_Java-Android-如何将txt文件上传到网站?

我想将txt文件上传到网站,我承认我没有对其进行任何详细的研究,但是我看了一些示例,并希望就我是否朝着正确的方向提出更多的经验性意见. .这是我到目前为止的内容:DefaultHttpClient httpClient new DefaultHttpClient();HttpContext localContext new BasicHttp…

java授查 非授查异常_java检查异常与非检查异常

Java的可检测异常和非检测异常泾渭分明。可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则。非检测异常不遵循处理或声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是…

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 SE 7的发布,二进制符号标准开箱即用。语法是非常直接和明显的,如果你有一个良好的理解二进制:byte fourTimesThree 0b1100;byte data 0b0000110011;short number 0b111111111111111;int overflow 0b10101010101…

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

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

java二重循环计数_java的二重循环代码样例

1.计算三个班的平均分import java.util.Scanner;public class AvgScore{public static void main (Sting[] args){int[] score new int[]; //成绩数组int classNum 3; //班级数量double sun 0.0; //成绩总和double[] average new double[classNum];//平均成绩…

java语言sql接口_Java语言SQL接口

Java语言SQL接口编辑锁定讨论上传视频《Java语言SQL接口》是1997年清华大学出版社出版的图书,作者是孙元等。本书覆盖了JDBC的各个方面,适合于有一定的Java语言编程基础和数据库及SQL语言基础的开发人员使用。作 者孙元 / …

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 文件树形_java 显示树形文件结构,类似windows的tree命令

本来是个练习题,自己做了做,还行。但是看到别人的代码比我的更好。所以,这里就贴出了别人的代码。我的就只有让它沉睡吧……。是别人的,算是转载吧。转自:他的电脑。主要思想,递归调用。import java.io.Fil…

hdfs的实验总结_实验2-熟悉常用的HDFS操作.doc

本文档下载自 文库下载网,/doc/d52aebffbb0d4a7302768e9951e79b896802689c.html实验2-熟悉常用的HDFS操作实验2熟悉常用的HDFS操作1实验目的1. 理解HDFS在Hadoop体系结构中的角色;2. 熟练使用HDFS操作常用的Shell命令;3. 熟悉HDFS操作常用的J…

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

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

计算两个数的乘积java编写_Java模拟计算机的整数乘积计算功能示例

本文实例讲述了Java模拟计算机的整数乘积计算功能。分享给大家供大家参考,具体如下:计算机计算整数乘积的原理:实现代码:package math;public class two {/*** Fundamental method* f(n) O(n^2)* param a* param b* return*/publ…

java使用linux常用命令_linux常用Java程序员使用命令(一)

pwd 显示当前路径cd切换目录 . .. ~ls显示文件(夹)-l 显示详细信息-a显示全部,包括隐藏文件(夹)mkdir创建文件夹-p递归创建touch创建空白文件echocat、tac、more、tail 查看文本内容rmdir删除空白文件夹rm-f 强制删除-r递归删除cp复制/新建文件mv移动/重命名find查找…

java中start与loop_java for-loop问题

我正在制作一个Java程序来计算Simpson的积分规则.这是我的代码.注意count 4,9,10,11的输出值中的第二列数字.它们不是我需要的数字,它们不遵循这种模式.我需要这些数字是准确的.发生了什么,我该如何解决?public static void main(String[] args){double totalS 0.…

java查询数据库的方式_Java连接各种数据库方式速查表

1、Oracle8/8i/9i数据库(thin模式)Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();String url"jdbc:oracle:thin:localhost:1521:orcl"; //orcl为数据库的SIDString user"test";String password"test";Connection c…

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…