前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(14)Struts2_值栈

(14)Struts2_值栈

作者头像
qubianzhong
发布2018-09-19 13:06:39
3710
发布2018-09-19 13:06:39
举报
文章被收录于专栏:行者常至

Struts2_值栈

借用在前面演示 hello world 的时候的例子。
在show.jsp 页面那些字段的值到底是怎么取得呢?现在在show.jsp中输出request
代码语言:javascript
复制
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  <body>
       ID:${id}<br>
       编号:${ dlh}<br>
       姓名:${ name}<br>
       部门:${ bmmc}<br>
      <%=request %>
  </body>
</html>
这里写图片描述
这里写图片描述
可见,request是经过Struts包装过后的。
ctrl+shift+t 查看StrutsRequestWrapper类的 源码
代码语言:javascript
复制
public class StrutsRequestWrapper extends HttpServletRequestWrapper {

    private static final String REQUEST_WRAPPER_GET_ATTRIBUTE = "__requestWrapper.getAttribute";
    private final boolean disableRequestAttributeValueStackLookup;

    ......

    /**
     * Gets the object, looking in the value stack if not found
     *
     * @param key The attribute key
     */
    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;
    }
}
当从super.getAttribute(key)获取不到值时,会从ValueStack中去取,super即HttpServletRequestWrapper 。所以,页面输出的值是从值栈里面取到的值,而并非是request请求域中有这么一些属性值。
debug断点调式
这里写图片描述
这里写图片描述
ActionContext其实是对OgnlContext的包装。
root即为实际意义上的后进先出的一个栈;值栈在页面取值输出的时候,就是从root属性里取其所含的对象的属性的值。
其中root属性为CompoundRoot对象,查看其源码可知。
代码语言:javascript
复制
public class CompoundRoot extends CopyOnWriteArrayList<Object> {

    private static final long serialVersionUID = 8563229069192473995L;

    public CompoundRoot() {
    }

    public CompoundRoot(List<?> list) {
        super(list);
    }


    public CompoundRoot cutStack(int index) {
        return new CompoundRoot(subList(index, size()));
    }

    public Object peek() {
        return get(0);
    }

    public Object pop() {
        return remove(0);
    }

    public void push(Object o) {
        add(0, o);
    }
}
其继承了list,进栈push添加到第一个,其前的往后移;出栈删除第一个,其后的往前移。

总结:

ValueStack(值栈):

I. 可以从 ActionContext 中获取值栈对象
II. 值栈分为两个逻辑部分
  • Map 栈: 实际上是 OgnlContext 类型, 是个 Map, 也是对 ActionContext 的一个引用. 里边保存着各种 Map: requestMap, sessionMap, applicationMap, parametersMap, attr
  • 对象栈: 实际上是 CompoundRoot 类型, 是一个使用 ArrayList 定义的栈. 里边保存各种和当前 Action 实例相关的对象.是一个数据结构意义的栈.

贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.

Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中

这里写图片描述
这里写图片描述

在 ValueStack 对象的内部有两个逻辑部分:
  • ObjectStack: Struts 把 Action 和相关对象压入 ObjectStack 中
  • ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中. 实际上就是对 ActionContext 的一个引用
Struts 会把下面这些映射压入 ContextMap 中
  • parameters: 该 Map 中包含当前请求的请求参数
  • request: 该 Map 中包含当前 request 对象中的所有属性
  • session: 该 Map 中包含当前 session 对象中的所有属性
  • application:该 Map 中包含当前 application 对象中的所有属性
  • attr: 该 Map 按如下顺序来检索某个属性: request, session, application
这里写图片描述
这里写图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年09月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Struts2_值栈
    • 借用在前面演示 hello world 的时候的例子。
      • 在show.jsp 页面那些字段的值到底是怎么取得呢?现在在show.jsp中输出request
        • 可见,request是经过Struts包装过后的。
          • ctrl+shift+t 查看StrutsRequestWrapper类的 源码 。
            • 当从super.getAttribute(key)获取不到值时,会从ValueStack中去取,super即HttpServletRequestWrapper 。所以,页面输出的值是从值栈里面取到的值,而并非是request请求域中有这么一些属性值。
              • debug断点调式
                • ActionContext其实是对OgnlContext的包装。
                  • root即为实际意义上的后进先出的一个栈;值栈在页面取值输出的时候,就是从root属性里取其所含的对象的属性的值。
                    • 其中root属性为CompoundRoot对象,查看其源码可知。
                      • 其继承了list,进栈push添加到第一个,其前的往后移;出栈删除第一个,其后的往前移。
                      • 总结:
                      • ValueStack(值栈):
                        • I. 可以从 ActionContext 中获取值栈对象
                          • II. 值栈分为两个逻辑部分
                            • 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.
                              • Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中
                                • 在 ValueStack 对象的内部有两个逻辑部分:
                                  • Struts 会把下面这些映射压入 ContextMap 中
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档