现在的位置: 首页 > 综合 > 正文

Strurts2请求过程分析

2012年05月25日 ⁄ 综合 ⁄ 共 3786字 ⁄ 字号 评论关闭

根据web.xml中的url规则拦截配置

 

未命名

 

如果匹配则被org.apache.struts2.dispatcher.FilterDispatcher拦截,执行方法doFilter(ServletRequest req, ServletResponse res, FilterChain chain)。

request = prepareDispatcherAndWrapRequest(request, response);在这里面会设置request 的defaultEncoding,response的defaultLocale。

 

1. mapping=actionMapper.getMapping(request,dispatcher.getConfigurationManager());

从url得到 namespace,name,action,,method构建ActionMapping对象,以在struts.xml中寻找相应的package中的action来执行。

1.1. 类:org.apache.struts2.dispatcher.mapper. DefaultActionMapper

方法:parseNameAndNamespace(String uri, ActionMapping mapping,

ConfigurationManager configManager)

执行后得到namespace和name.

1.2. 类:org.apache.struts2.dispatcher.mapper. DefaultActionMapper

方法:parseActionName(mapping);

从形如action!method分解出method

 

2. staticResourceLoader.findStaticResource(resourcePath, request, response);

如果根据ActionMapping找不到action配置适配请求,那么就认为此url请求的是静态文件,去相应的静态文件夹下尝试找静态文件,找到即返回

类:org.apache.struts2.dispatcher.DefaultStaticContentLoader

方法:public void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response)

String name = cleanupPath(path);

清除url中表示静态文件的部分

URL resourceUrl = findResource(buildPath(name, pathPrefix));

然后在前面加上可自定义的pathPrefixes在classpath中寻找,找到则返回,找不到则转交FilterChain处理,这里给外挂servlet提供了出口。

 

3. dispatcher.serviceAction(request, response, servletContext, mapping);

类:org.apache.struts2.dispatcher.FilterDispatcher

方法:void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,

ActionMapping mapping)

执行interceptor,Action,最后进行 Result的渲染

 

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

类:org.apache.struts2.dispatcher.FilterDispatcher

方法:Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,

ActionMapping mapping, ServletContext context)

创建extraContext,并在其_values属性里面存放了request,session,application, parameters,attr等常用servlet对象。最后把actionMapping, valuestack也放入。

 

3.2. ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);

类:com.opensymphony.xwork2.DefaultActionProxyFactory

方法:ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext)

根据namespace,name,method创建相应的ActionProxy

 

2.2.1. 在类DefaultActionProxyFactory中创建ActionInvocation,

ActionInvocation inv = new DefaultActionInvocation(extraContext, true);

 

2.2.2 invocation.init(this);

类:com.opensymphony.xwork2.DefaultActionInvocation

方法:void init(ActionProxy proxy)

 

a. createAction(contextMap);

类:com.opensymphony.xwork2.DefaultActionInvocation

方法:createAction(Map<String, Object> contextMap)

Object buildAction(String actionName, String namespace, ActionConfig config, Map<String, Object> extraContext)

类:com.opensymphony.xwork2.ObjectFactory

方法:public Object buildAction(String actionName, String namespace, ActionConfig config, Map<String, Object> extraContext)

针对每次请求新建一个Action, 当使用spring作为bean的容器时,SpringObjectFactory先去spring的ApplicationContext中找,找不到则直接创建一个Action,并将spring 容器中构建好的属性的值填充入Action.

b. List<InterceptorMapping> interceptorList = new ArrayList<InterceptorMapping>(proxy.getConfig().getInterceptors());

interceptors = interceptorList.iterator();

得到所有拦截器,以作拦截

 

2.3.proxy.execute();执行调用

2.3.1 invocation.invoke();

类: com.opensymphony.xwork2.DefaultActionInvocation

方法:public String invoke()

resultCode =interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

在interceptor里面也调用invocation.invoke方法。通过对全局变量interceptors的next()调用不停地执行interceptor.intercept()。最后调用resultCode = invokeActionOnly();

String invokeAction(Object action, ActionConfig actionConfig) throws Exception

调用Action的相应Method,默认调用execute():

method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);

methodResult = method.invoke(action, new Object[0]);

 

2.4. executeResult();

 

3.dispatcher.cleanUpRequest(request);

抱歉!评论已关闭.