一, org.apache.struts2.dispatcher.FilterDispatcher 初始化
public void init(FilterConfig filterConfig) throws ServletException {
try {
this.filterConfig = filterConfig;
initLogging();
dispatcher = createDispatcher(filterConfig); //初始化dispatcher dispatcher.init();
dispatcher.getContainer().inject(this);
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
} finally {
ActionContext.setContext(null); }
}
//下面就是初始化dispatcher public void init() {
if (configurationManager == null) {
;
}
try {
//加载org/apache/struts2/default.properties init_DefaultProperties(); // [1]
//首先读取web.xml中的config初始参数值
//如果没有配置就使用默认的\"struts-default.xml,struts-plugin.xml,struts.xml\" init_TraditionalXmlConfigurations(); // [2] init_LegacyStrutsProperties(); // [3] //加载Web.xml中配置的xml
init_CustomConfigurationProviders(); // [5] init_FilterInitParameters() ; // [6] init_AliasStandardObjects() ; // [7]
Container container = init_PreloadConfiguration(); container.inject(this);
configurationManager = new
ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME)
init_CheckConfigurationReloading(container); init_CheckWebLogicWorkaround(container);
if (!dispatcherListeners.isEmpty()) {
for (DispatcherListener l : dispatcherListeners) { l.dispatcherInitialized(this); } }
} catch (Exception ex) { if (LOG.isErrorEnabled())
LOG.error(\"Dispatcher initialization failed\", ex); throw new StrutsException(ex); }
}
二,
Struts2请求流程
1、客户端发送请求
2、请求先通过ActionContextCleanUp-->FilterDispatcher 3、FilterDispatcher创建ActionMapping 和serviceAction
ActionMapping设置扩展名,Namespace,ActionName,Method(这里只处理!请示的方法如user!aadd.action)
ServiceAction创建ActionProxy代理,执行代理
4、ActionProxy 准备工作(1)、查找命名空间,在空间中查找对应的Action [查找方法:
是先安全名匹配Action,如果没有则按类拟与user-*这种形式匹配],如果找到装载Action 中的配置
(2)在Action类中查找对应的方法,如果没有则用execute方法
(3)初始化Action (方法先找Bean中是否有,如果没有则跟据类实例化)
5、ActionProxy创建一个ActionInvocation的实例,ActionInvocation调用真正的Action,当然这涉及到相关的调用(其中有参数封装,封装异常等等,最后一个是调用Action)
6、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现,
7、ResultCode跟据返回的值,查找对应ResultConfig对象(查找方法先跟据Name找,如果没有则查找*的)跟据不用的Type配置,得到不同的resultClassName,实后实列化并设置参数,调用doExecute方法返回
注:resultClassName有以后几种 Type默认时:
resultClassName=
org.apache.struts2.dispatcher.ServletDispatcherResult Type=redirectAction resultClassName=
org.apache.struts2.dispatcher.ServletActionRedirectResult Type=tiles
resultClassName=org.apache.struts2.views.tiles.TilesResult
对应调用的方法: Forword Redirect Render
8、Struts2的查找值和设置值都是使用Ognl来实现的。关于Ognl的介绍可以到其官方
网站查看http://www.ognl.org/
这样,一个Struts2的请求流程基本上就结束了
mapping=actionMapper.getMapping(request, dispatcher.getConfigurationManager());
//创始ActionMapping
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) { ActionMapping mapping = new ActionMapping(); String uri = getUri(request);//得到请示Url
int indexOfSemicolon = uri.indexOf(\";\");
uri = (indexOfSemicolon > -1) ? uri.substring(0, indexOfSemicolon) : uri;
uri = dropExtension(uri, mapping);//去掉后缀 if (uri == null) { return null; }
//设置NameSpance和ActionName
parseNameAndNamespace(uri, mapping, configManager);
handleSpecialParameters(request, mapping);
if (mapping.getName() == null) { return null; }
//处理以!的方法
parseActionName(mapping);
return mapping;
}
//ServiceAction方法
dispatcher.serviceAction(request,response,servletContext,mapping);
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {
Map // 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); boolean nullStack = stack == null; if (nullStack) { ActionContext ctx = ActionContext.getContext(); if (ctx != null) { stack = ctx.getValueStack(); } } if (stack != null) { extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.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(); //创建Acton 代理 ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack()); // if the ActionMapping says to go straight to a result, do it! if (mapping.getResult() != null) { Result result = mapping.getResult(); result.execute(proxy.getInvocation()); } else { proxy.execute(); } // If there was a previous value stack then set it back onto the request if (!nullStack) { request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); } } catch (ConfigurationException e) { // WW-2874 Only log error if in devMode if(devMode) { } else { } sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e); LOG.warn(\"Could not find action or result\", e); LOG.error(\"Could not find action or result\", e); } catch (Exception e) { sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } finally { UtilTimerStack.pop(timerKey); } } //准备代理 proxy.prepare(); protected void prepare() { String profileKey = \"create DefaultActionProxy: \"; try { UtilTimerStack.push(profileKey); //查找匹配的ActionConfig对象 //查找命名空间,在空间中查找对应的Action [查找方法:是先安全名匹配Action,如果没//有则按类拟与user-*这种形式匹配],如果找到装载Action 中的配置 config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName); if (config == null && unknownHandlerManager.hasUnknownHandlers()) { config = unknownHandlerManager.handleUnknownAction(namespace, actionName); } if (config == null) { String message; if ((namespace != null) && (namespace.trim().length() > 0)) { message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_PACKAGE_ACTION_EXCEPTION, Locale.getDefault(), new String[]{ namespace, actionName }); } else { message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_ACTION_EXCEPTION, Locale.getDefault(), new String[]{ actionName }); } throw new ConfigurationException(message); } //在Action类中查找对应的方法,如果没有则用execute方法 resolveMethod(); if (!config.isAllowedMethod(method)) { throw new ConfigurationException(\"Invalid method: \"+method+\" for action \"+actionName); } //初始代理 invocation.init(this); } finally { UtilTimerStack.pop(profileKey); } //创始Action public Object buildBean(String beanName, Map o = appContext.getBean(beanName); } catch (NoSuchBeanDefinitionException e) { Class beanClazz = getClassInstance(beanName); o = buildBean(beanClazz, extraContext); } if (injectInternal) { injectInternalBeans(o); } return o; } //执行代理 proxy.execute(); public String invoke() throws Exception { String profileKey = \"invoke: \"; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException(\"Action has already executed\"); } if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); String interceptorMsg = \"interceptor: \" + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { //执行栈中的(大约有15个左右)包扩参数封装,最后一个是捃行Action中的方法 resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } } else { resultCode = invokeActionOnly(); } // this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) { //查看是否配置了返回前监听事件,用户可以自己写事件,但要实理preResultListeners接口 if (preResultListeners != null) { for (Object preResultListener : preResultListeners) { PreResultListener listener = (PreResultListener) preResultListener; String _profileKey = \"preResultListener: \"; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we're supposed to if (proxy.getExecuteResult()) { //执行返回 方法 executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } } //执行返回方法 private void executeResult() throws Exception { //创建返回对象,跟据不同的type创建不用的对象 result = createResult(); String timerKey = \"executeResult: \" + getResultCode(); try { UtilTimerStack.push(timerKey); if (result != null) { //执行方法 result.execute(this); } else if (resultCode != null && !Action.NONE.equals(resultCode)) { throw new ConfigurationException(\"No result defined for action \" + getAction().getClass().getName() + \" and result \" + getResultCode(), proxy.getConfig()); } else { if (LOG.isDebugEnabled()) { LOG.debug(\"No result returned for action \" + getAction().getClass().getName() + \" at \" + proxy.getConfig().getLocation()); } } } finally { UtilTimerStack.pop(timerKey); } }
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务