咨询一个问题,struts2是在什么时候将action的执行后的数据传递到request的属性struts.valueStack中去的?举例说明: action 中有查找学生记录的方法findStudents ,他将查找到的学生记录存放到了list中,那么这个list是在什么时候赋给request的attribute中去的?源代码是哪个java类?

解决方案 »

  1.   

    gvc068932 谢谢。这个我知道,我是想深入的了解,究竟是哪段源代码实现了这个功能?如何实现的?在哪个java类中?
      

  2.   

    惭愧!源代码读了很多,struts2的执行流程和拦截器都比较清除了。就是没有找到action的执行后的数据传递到request的属性struts.valueStack中去的源代码。
      

  3.   

        /**
         * Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.
         * <p/>
         * This method first creates the action context from the given parameters,
         * and then loads an <tt>ActionProxy</tt> from the given action name and namespace.
         * After that, the Action method is executed and output channels through the response object.
         * Actions not found are sent back to the user via the {@link Dispatcher#sendError} method,
         * using the 404 return code.
         * All other errors are reported by throwing a ServletException.
         *
         * @param request  the HttpServletRequest object
         * @param response the HttpServletResponse object
         * @param mapping  the action mapping object
         * @throws ServletException when an unknown error occurs (not a 404, but typically something that
         *                          would end up as a 5xx by the servlet container)
         * @param context Our ServletContext object
         */
        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
                                  ActionMapping mapping) throws ServletException {        Map<String, Object> extraContext = createContextMap(request, response, mapping, context);        // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
            ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);System.out.println("stack"+stack);
            if (stack != null) {System.out.println("stack!=null"+"If there was a previous value stack, then create a new copy and pass it in to be used by the new Action");//added by wangmj 20080923
                extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));
            }        String timerKey = "Handling request from Dispatcher";
            try {
                UtilTimerStack.push(timerKey);
                String namespace = mapping.getNamespace();
                String name = mapping.getName();
                String method = mapping.getMethod();            Configuration config = configurationManager.getConfiguration();
                ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                        namespace, name, extraContext, true, false);//生成ActionProxy实例
                proxy.setMethod(method);//设定要调用的方法名
                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());//必须放在action执行之前,经过测试,放在后面程序失败!
                System.out.println("wangmingjie-valueStack"+proxy.getInvocation().getStack());
                // if the ActionMapping says to go straight to a result, do it!
                if (mapping.getResult() != null) {//直接跳转到某个jsp文件 xml配置文件中没有class的配置项
                    Result result = mapping.getResult();
                    result.execute(proxy.getInvocation());
                } else {
                    proxy.execute();//真正执行action的方法
                }
                System.out.println("stack-after-execute"+stack);
                // If there was a previous value stack then set it back onto the request
                if (stack != null) {System.out.println("stack!=null"+"If there was a previous value stack then set it back onto the request");//added by wangmj 20080923
                    request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);//第二次设置
                }
            } catch (ConfigurationException e) {
                LOG.error("Could not find action or result", e);
                sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
            } catch (Exception e) {
                throw new ServletException(e);
            } finally {
                UtilTimerStack.pop(timerKey);
            }
        }
      

  4.   

    答案:通过OgnlValueStack获取到的。
    而在DefaultActionInvocation中有这么一段 
    Java代码  
    1. private void init() throws Exception {   
    2.     Map contextMap = createContextMap();   
    3.   
    4.     createAction();   
    5.   
    6.     if (pushAction) {   
    7.         stack.push(action);   
    8.     }   
    9.     //...  
    表明在action被执行前 它已经被放到valuestack里面去了 
      

  5.   

    package xwork;import com.opensymphony.xwork2.util.OgnlValueStack;/**
     * @author wangmingjie
     * @date 2008-9-26下午02:38:04
     */
    public class TestAction { private String id = "avx"; public String execute() { System.out.println("id in action: " + id); this.id = "sssssssss"; return "success";
    } public String getId() {
    return com.work.util.DateUtil.getCurrentDateTime();
    } public void setId(String id) {
    this.id = id;
    }
    public static void main(String[] args){

    TestAction action = new TestAction();    
       
    OgnlValueStack valueStack = new OgnlValueStack();    
    valueStack.push(action);    
       
    //进    
    valueStack.setValue("id", "aaaaaaaaa");    
       
    //改变值    
    action.execute();    
       
    //出    
    System.out.println("id after change: " + valueStack.findValue("id"));  
    }
    }