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

 

原文地址:https://www.cnblogs.com/sdnu/p/5356779.html