/** * 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); } }
* 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);
}
}
而在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里面去了
* @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"));
}
}