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中获取的。

     

  • 相关阅读:
    LeetCode 811. Subdomain Visit Count (子域名访问计数)
    LeetCode 884. Uncommon Words from Two Sentences (两句话中的不常见单词)
    LeetCode 939. Minimum Area Rectangle (最小面积矩形)
    LeetCode 781. Rabbits in Forest (森林中的兔子)
    LeetCode 739. Daily Temperatures (每日温度)
    三种方式实现按钮的点击事件
    239. Sliding Window Maximum
    14.TCP的坚持定时器和保活定时器
    13.TCP的超时与重传
    12.TCP的成块数据流
  • 原文地址:https://www.cnblogs.com/sdnu/p/5356779.html
Copyright © 2011-2022 走看看