值栈(ValueStack)
http://www.cnblogs.com/bgzyy/p/8639893.html 这是我的有关 struts2 的第一篇文章,对于里面我们说到的一个 struts2 HelloWorld 小练习,即在输入框输入信息提交后在另外一个页面显示输入的信息,显示页面的代码如下:
UserName: ${userName}<br>
Email: ${email}<br>
Address: ${address}<br>
为什么这样一个简单的标签就可以获取到另外一个页面的输入信息,我们使用上面链接中的代码并在其基础上加以改进以得到答案!
我们知道 struts 默认的请求类型为 dispatcher,即请求转发,那么我们尝试在 show.jsp 中利用 request 域对象打印输入值,如下(在前面加上标识以区分):
UserDesc: ^+^<%= request.getAttribute("userDesc")%><br>
结果如下图:
-
我们可以看到利用 request 的 getAttribute() 方法打印的结果和使用标签一样,此时我们应该想到将 request 打印出来,代码以及结果如下:
Request: <%= request%>
如上图所示,此时的 request 是已经被 struts2 封装的 request,在 IDEA 中双击 Shift 查找 StrustsRequestWrapper 源代码,找到其 getAttributte() 方法,如下:
public class StrutsRequestWrapper extends HttpServletRequestWrapper {
public Object getAttribute(String key) {
if (key == null) {
throw new NullPointerException("You must specify a key value");
}
if (disableRequestAttributeValueStackLookup || key.startsWith("javax.servlet")) {
// don't bother with the standard javax.servlet attributes, we can short-circuit this
// see WW-953 and the forums post linked in that issue for more info
return super.getAttribute(key);
}
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(key);
if (ctx != null && attribute == null) {
boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE));
// note: we don't let # come through or else a request for
// #attr.foo or #request.foo could cause an endless loop
if (!alreadyIn && !key.contains("#")) {
try {
// If not found, then try the ValueStack
ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.TRUE);
ValueStack stack = ctx.getValueStack();
if (stack != null) {
attribute = stack.findValue(key);
}
} finally {
ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.FALSE);
}
}
}
return attribute;
}
}
- 如上代码所示,我们可以知道 StrutsRequestWrapper 继承自 HttpServletRequestWrapper
- getAttribute() 方法首先判断传入的 key 是否为空,若是抛出空指针异常
- 若不是判断传入的 key 值是否满足一定的条件,若满足则直接使用父类的 getAttribute() 方法,获取对应的属性值
- 若不满足则经过一系列判断后获取到 ValueStack 对象 stack,从 stack 对象中获得对应 key 的属性,并返回
为了一探究竟我们 Debug 一步步调试查看,首先 Debug 运行程序,在输入页面输入信息之后再在源代码页面上打断点(在源代码页面的 ValueStack 前一行打断点),再点击提交将会跳转到调试页!
- 第一次运行至断点结果如下图所示,这是 struts2 初始化一些必要的信息
- 将光标放置在断点行,点击 Run to Cursor(运行至光标处),直到 key 的值为 userName,再点击将依次 userDesc 等,如图
- 此时点击Step Over 执行代码到下一行,ValueStack 对象将被初始化,如下图所示,在这里我们依次打开 stack,root 在这里我们可以看到一对一对的 key 和 value ,进而我们得知显示页面的值是从此处得来的
- 一些关于值栈的概念
- ValueStack(值栈):贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.
- 在 ValueStack 对象的内部有两个逻辑部分,ObjectStatck 和 ContextMap;
- struts 把 Action 和相关对象(如上例中的 Info 对象)压入ObjectStack 中,这里所说的 ObjetcMap 即上图中的 root,遵循“先进后出” 的原则
- ContextMap:Struts 把各种映射关系压入 ContextMap 中,实际上就是一些对 ActionContext 的引用(parameters、request、session、application、attr)
至此我们得知显示页面的底层实现,即从 ValueStack 中获取,其默认从栈顶开始寻找与 key 值匹配的属性,依次往下,也了解到值栈的基本概念,接下来让我们着手利用 OGNL 获取值栈里对象的属性。
OGNL
-
在 JSP 页面上利用 OGNL 访问值栈里对象的属性,若希望访问值栈中 ContextMap 中的数据,需要给 OGNL 表达式前面加上一个前缀 #,如果没有添加将会在 ObjectStack 中进行,如下示例在 session 内找 key 为 sessionMap 的属性
<s:property value="#session.sessionMap"/>
-
property 标签
- Struts2 的 property 标签用来输出值栈中的一个属性值
- 其属性 value 表示来自栈顶对象在页面上将要显示的值(String 类型)
- 其属性 default 表示若 value 若为空,将显示该值(String 类型)
- 其属性escape 表示是否对 HTML 特殊字符进行转义
-
读取规则
读取 ObjectStack 里的对象的属性,ObjectStack 里的对象可以通过一个从零开始的下标来引用,即可以使用[0].userName 来返回栈顶对象的 message 属性,结合 <s:property> 标签
若在指定的对象中没有找到指定的属性,则到指定对象的下一个对象里继续搜索,即 [n] 的意义是从第 n 个开始搜索,而不是只搜索第 n 个
若从栈顶对象开始搜索则可以省略下标
-
默认情况下 Action 对象会被 Struts2 自动的放到值栈的栈顶
// 如下两种写法都是从栈顶开始在对象栈中查找 key 为 userName 的属性
<s:property value="userName"/>
<s:property value="[0].userName"/>
Struts2 之值栈的更多相关文章
-
struts2(二)值栈 threadlocal ogal ui
值栈(重要)和ognl表达式 1. 只要是一个mvc框架,必须解决数据的存和取的问题 2. Struts2利用值栈来存数据,所以值栈是一个存储数据的内存结构 3. 把数据存在值栈中,在页面上利用 ...
-
Struts2的值栈和OGNL牛逼啊
Struts2的值栈和OGNL牛逼啊 一 值栈简介: 值栈是对应每个请求对象的一套内存数据的封装,Struts2会给每个请求创建一个新的值栈,值栈能够线程安全的为每个请求提供公共的数据存取服务. 二 ...
-
【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
一.struts2系统验证 1.基于struts2系统验证的方式实际上就是通过配置xml文件的方式达到验证的目的. 2.实际上系统校验的方法和手工校验的方法在底层的基本实现是相同的.但是使用系统校验的 ...
-
Struts2向值栈中压入属性的方式
Struts2在初始化Action的时候会先向值栈中压入一个action对象,里面包含了各个属性,这些属性是怎么被压进去的?或者说是根据什么来压入的?直到2016年5月5日才理解,原来是在初始化act ...
-
Struts2 的 值栈和ActionContext
1.ValueStack 和 ActionContext 的关系与区别: -- 相同点:它们都是在一次HTTP请求的范围内使用的,它们的生命周期都是一次请求 -- 不同点:ValueStack 分为对 ...
-
Struts2的值栈和对象栈
ValueStack 如何得到值栈: 如何将对象存入值栈: 让值栈执行表达式来获得值: 在JSP中跳过栈顶元素直接访问第二层: 在JSP中访问值栈对象本身(而不是它们的属性) ActionContex ...
-
【struts2】值栈(后篇)
在值栈(前篇)我们学习了值栈的基本知识,接下来,来看看在程序中具体如何使用值栈. 1 ActionContext的基本使用 1.1 如何获取? 要获取ActionContext有两个基本的方法,如果在 ...
-
【struts2】值栈(前篇)
1 值栈是什么? 简单的说:值栈是对应每一个请求对象的轻量级的内存数据中心. Struts2中一个很激动人心的特性就是引入了值栈,在这里统一管理着数据,供Action.Result.Intercept ...
-
struts2框架值栈的概述之问题一:什么是值栈?
1. 问题一:什么是值栈? * 值栈就相当于Struts2框架的数据的中转站,向值栈存入一些数据.从值栈中获取到数据. * ValueStack 是 struts2 提供一个接口,实现类 OgnlVa ...
随机推荐
-
IntelliJ IDEA 中文乱码问题解决办法
自己最近在使用IntelliJ IDEA,发现总是出现中文乱码的问题,在网上找了很多教程,发现真是“天下文章一大抄”.还不如自己动手试着解决一下. 1.编辑器以及调试信息中文乱码问题 解决方案: 选择 ...
-
终于下决心在cnblogs上安家了,^_^
以前在这个地方学到了很多东西,希望在这里安家以后,自己也可以有很多成长. mark一下,~~
-
SQLMap入门之在Windows上安装SQLMap
前言: SQLMap是一个开放源代码的sql注入工具,SQLMap是使用Python语言开发成的,他的运行需要有Python环境的支持.写这篇文章时我使用的SQLMap版本是"sqlmap- ...
-
[dev][ipsec] netlink是什么
介绍: https://www.linuxjournal.com/article/7356 大纲: man手册 http://man7.org/linux/man-pages/man7/netlink ...
-
jenkins中配置svn 出现absolute path is not allowed
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 想用jenkins作自动化部署tomcat. svn代码已经checkout到本地目录了(/ ...
-
[OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...
-
PHP网站环境搭配: Apache Http+PHP+Mysql
Apache Http+PHP+Mysql 环境搭配 1. 先下载上述三个软件 都要下载对应系统的软件,mysql还可以再下载navicat for mysql. 2. 安装Apache Http ...
-
Java使用FFmpeg处理视频文件指南
Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频 ...
-
jenkins maven设置settings.xml
环境:jenkins.2.89.3 1.安装settings.xml管理插件Config File Provider Plugin 系统管理->管理插件->搜索Config File P ...
-
HTML页面为什么设置了UTF-8仍然中文乱码
如题,其实问题很简单,在用EditPlus写html页面的时候,发现设置为UTF-8的时候仍然出现了乱码,这是一个很奇怪的问题,而且我完全考虑了浏览器的解析问题,将title放在了了meta标签之后, ...