刨根问底struts获得request(ServletActionContext.getReq...

在使用struts框架中,经常使用ServletActionContext.getRequest()获得request对象,现在就看看ServletActionContext.getRequest()源码:

/**
     * Gets the HTTP servlet request object.
     *
     * @return the HTTP servlet request object.
     */
    public static HttpServletRequest getRequest() {
        return (HttpServletRequest) ActionContext.getContext().get(HTTP_REQUEST);
    }
注释:这里很简单继续调用ActionContext中getContext()方法获取 ActionContext对象,在调用 ActionContext对象中get()获取request对象,下面详细看看:


public class ActionContext implements Serializable {
    static ThreadLocal actionContext = new ThreadLocal();
    Map<String, Object> context;

   public ActionContext(Map<String, Object> context) {
        this.context = context;
    }
/**
     * Returns the ActionContext specific to the current thread.
     *
     * @return the ActionContext for the current thread, is never <tt>null</tt>.
     */
    public static ActionContext getContext() {
        return (ActionContext) actionContext.get();
    }

  public Object get(String key) {
        return context.get(key);
    }
注释:(1)ActionContext类首先定义了一个类型ThreadLocal的actionContext对象,这样保证每个线程获得actionContext对象时安全。


(2)ActionContext类中getContext()方法,获取相应线程上ActionContext对象

(3)ActionContext类中定义了类型Map<String, Object>的context对象,context中保存了request,actionMapping等相应的信息

(4)ActionContext类中get()方法,在context获取key为HTTP_REQUEST = "com.opensymphony.xwork2.dispatcher.HttpServletRequest"对应的对象。


到这里分析完成获取request的整个过程,那是怎么添加进来的呢?

DefaultActionProxy中的execute()方法:

public String execute() throws Exception {
        ActionContext nestedContext = ActionContext.getContext();
        ActionContext.setContext(invocation.getInvocationContext());                            。。。                                                                           retCode = invocation.invoke()
这里设置ActionContext对象,然后执行action,看来很很合理啊!

public class DefaultActionInvocation implements ActionInvocation {

  protected ActionContext invocationContext;
  protected Map<String, Object> extraContext;

 public DefaultActionInvocation(final Map<String, Object> extraContext, final boolean pushAction) {
        DefaultActionInvocation.this.extraContext = extraContext;
        DefaultActionInvocation.this.pushAction = pushAction;
    }
  public ActionContext getInvocationContext() {
        return invocationContext;
    }

  public void init(ActionProxy proxy) {
        this.proxy = proxy;
        Map<String, Object> contextMap = createContextMap();

        // Setting this so that other classes, like object factories, can use the ActionProxy and other
        // contextual information to operate
        ActionContext actionContext = ActionContext.getContext();

        if (actionContext != null) {
            actionContext.setActionInvocation(this);
        }

        createAction(contextMap);

        if (pushAction) {
            stack.push(action);
            contextMap.put("action", action);
        }

        invocationContext = new ActionContext(contextMap);
        invocationContext.setName(proxy.getActionName());
。。。。
}

   protected Map<String, Object> createContextMap() {
        Map<String, Object> contextMap;

        if ((extraContext != null) && (extraContext.containsKey(ActionContext.VALUE_STACK))) {
            // In case the ValueStack was passed in
            stack = (ValueStack) extraContext.get(ActionContext.VALUE_STACK);

            if (stack == null) {
                throw new IllegalStateException("There was a null Stack set into the extra params.");
            }

            contextMap = stack.getContext();
        } else {
            // create the value stack
            // this also adds the ValueStack to its context
            stack = valueStackFactory.createValueStack();

            // create the action context
            contextMap = stack.getContext();
        }

        // put extraContext in
        if (extraContext != null) {
            contextMap.putAll(extraContext);
        }

        //put this DefaultActionInvocation into the context map
        contextMap.put(ActionContext.ACTION_INVOCATION, this);
        contextMap.put(ActionContext.CONTAINER, container);

        return contextMap;
    }
注释:(1)DefaultActionInvocation类变量extraContext类型为Map<String, Object>,保存整个actionContext相应的信息。

(2)DefaultActionInvocation类变量invocationContext,保存了ActionContext对象。

(3)DefaultActionInvocation的构造函数中,给变量extraContext赋值。

(4)DefaultActionInvocation的init()方法中创建ActionContext对象,并且赋值给变量invocationContext。

现在看看DefaultActionInvocation的创建的方法:请看《刨根问底-struts-serviceAction()创建并执行action》,现在我们就简单的看形参 Map<String, Object> extraContext开始创建的地方:

Dispatcher中serviceAction()方法:

Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
  public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
            ActionMapping mapping, ServletContext context) {


        // request map wrapping the http request objects
        Map requestMap = new RequestMap(request);


        // parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately
        Map params = new HashMap(request.getParameterMap());


        // session map wrapping the http session
        Map session = new SessionMap(request);


        // application map wrapping the ServletContext
        Map application = new ApplicationMap(context);


        Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);


        if (mapping != null) {
            extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
        }
        return extraContext;
    }
   public HashMap<String,Object> createContextMap(Map requestMap,
                                    Map parameterMap,
                                    Map sessionMap,
                                    Map applicationMap,
                                    HttpServletRequest request,
                                    HttpServletResponse response,
                                    ServletContext servletContext) {
        HashMap<String,Object> extraContext = new HashMap<String,Object>();
        extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
        extraContext.put(ActionContext.SESSION, sessionMap);
        extraContext.put(ActionContext.APPLICATION, applicationMap);


        Locale locale;
        if (defaultLocale != null) {
            locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
        } else {
            locale = request.getLocale();
        }


        extraContext.put(ActionContext.LOCALE, locale);
        //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode));


        extraContext.put(StrutsStatics.HTTP_REQUEST, request);
        extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
        extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);


        // helpers to get access to request/session/application scope
        extraContext.put("request", requestMap);
        extraContext.put("session", sessionMap);
        extraContext.put("application", applicationMap);
        extraContext.put("parameters", parameterMap);


        AttributeMap attrMap = new AttributeMap(extraContext);
        extraContext.put("attr", attrMap);


        return extraContext;
    }
上面的代码其实不难,就是各种map之间的关系,及其处理。请看:extraContext.put(StrutsStatics.HTTP_REQUEST, request);

这就是根源了。



转载于:https://my.oschina.net/winHerson/blog/107895

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值