zoukankan      html  css  js  c++  java
  • struts2笔记10-值栈

    1、问题

    提交页面:

    	<h4>注册产品</h4>
    	<form action="save.do" method="post">
    		pName:<input type="text" name="pName" /><br />
    		pDesc:<input type="text" name="pDesc" /><br />
    		pPrice:<input type="text" name="pPrice" /><br />
    		<input type="submit" value="submit" />
    	</form>
    

    响应页面:

    	<h4>详细信息</h4>
    	Name:${pName}<br/><br/>
    	Desc:${pDesc}<br/><br/>
    	Price:${pPrice}<br/><br/>
    

    ${pName},${pDesc},${pPrice},写法简单优雅,优雅的背后肯定有故事,struts2在背后帮我们做了些什么?

    2、StrutsRequestWrapper

    (1)打印出request看看

    request:<%=request %>
    
    request:org.apache.struts2.dispatcher.StrutsRequestWrapper@37c4d046 
    

    (2)StrutsRequestWrapper源码

    package org.apache.struts2.dispatcher;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.util.ValueStack;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import static org.apache.commons.lang3.BooleanUtils.isTrue;
    
    
    public class StrutsRequestWrapper extends HttpServletRequestWrapper {
    
        private static final String REQUEST_WRAPPER_GET_ATTRIBUTE = "__requestWrapper.getAttribute";
        private final boolean disableRequestAttributeValueStackLookup;
    
        /**
         * The constructor
         * @param req The request
         */
        public StrutsRequestWrapper(HttpServletRequest req) {
            this(req, false);
        }
    
        /**
         * The constructor
         * @param req The request
         * @param disableRequestAttributeValueStackLookup flag for disabling request attribute value stack lookup (JSTL accessibility)
         */
        public StrutsRequestWrapper(HttpServletRequest req, boolean disableRequestAttributeValueStackLookup) {
            super(req);
            this.disableRequestAttributeValueStackLookup = 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;
        }
    }
    

      从代码中可以看出,StrutsRequestWrapper重写了getAttribute,其中有一段核心代码如下:

                        ValueStack stack = ctx.getValueStack();
                        if (stack != null) {
                            attribute = stack.findValue(key);
                        }
    

      debug代码,可以看出${pName}等是从ValueStack中获取出来的

    3、ValueStack

      首先这是一个接口,里面有两个关键声明方法

    public abstract Map<String, Object> getContext();
    
    public abstract CompoundRoot getRoot();
    

      debug代码,可以发现ValueStack包括两个核心属性

    一个context,一个root,context里面包含的是一系列map,requestMap,applicationMap,sessionMap等;

    root是一个CompoundRoot对象,其实也是个map,这里面包括的就是我们自己Action对象了

    ${pName}等正是从这里查出来的,并非从request中获取的。

     

  • 相关阅读:
    微信开发笔记:修改公众号自定义菜单
    微信开发笔记:公众号获取access_token
    微信开发笔记:微信浏览器分享设置以及回调
    HTML5开发笔记:初窥CANVAS,上传canvas图片到服务器
    求解分组问题(百度面试题)
    Python求解啤酒问题(携程2016笔试题)
    Fiddler教程【转】
    求解朋友关系中的朋友圈数量
    HTTP协议详解【转】
    求解暗黑字符串(网易2017秋招)
  • 原文地址:https://www.cnblogs.com/sdnu/p/5356779.html
Copyright © 2011-2022 走看看