• Strurts2请求过程分析


    根据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);

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/jinspire/p/2142989.html
Copyright © 2020-2023  润新知