`

struts2 流程 简单描述

 
阅读更多

1、整体结构

  

2.几个概念

2.1 actionContext:  is the context in which an Action is executed. Each context is basically a container of objects an action needs for execution like the session, parameters, locale, etc.

    保存session,parameters等对象的是一个Map类型叫context对象。 其在内存中的快照如下:

 2.2 FilterDispatcher

 Master filter for Struts that handles four distinct responsibilities:

  • Executing actions
  • Cleaning up the ActionContext (see note)
  • Serving static content
  • Kicking off XWork's interceptor chain for the request lifecycle

Struts2.1.3之后用StrutsPrepareAndExecuteFilter 替换

 

2.3 Dsipatcher:

      struts真正用来转发的类。

     该类是线程安全的。因为它的实例是如下代码生成的   

1 private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
2   
3 public static Dispatcher getInstance() {
4     return instance.get();
5 }

     用来处理的方法是serviceAction

 

 

1 public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
2                               ActionMapping mapping) throws ServletException

与Action相关的信息如name result path 在ActionMapping中。ActionMapping 的定义

1 public class ActionMapping {
2     private String name;
3     private String namespace;
4     private String method;
5     private String extension;
6     private Map<String, Object> params;
7     private Result result;

2.4 ActionInvocation:如何创建,执行Action。实现类DefaultActionInvocation。包含的对象有

01 protected Object action;
02     protected ActionProxy proxy;
03     protected List<PreResultListener> preResultListeners;
04     protected Map<String, Object> extraContext;
05     protected ActionContext invocationContext;
06     protected Iterator<InterceptorMapping> interceptors;
07     protected ValueStack stack;
08     protected Result result;
09     protected Result explicitResult;
10     protected String resultCode;
11     protected boolean executed = false;
12     protected boolean pushAction = true;
13     protected ObjectFactory objectFactory;
14     protected ActionEventListener actionEventListener;
15     protected ValueStackFactory valueStackFactory;
16     protected Container container;
17     private Configuration configuration;
18     protected UnknownHandlerManager unknownHandlerManager;

 

     核心方法是invoke()

1 interceptor.getInterceptor().intercept(DefaultActionInvocation.this);//调用拦截器
2 invokeActionOnly();//调用Action

    其中invokeActionOnly(Object action, ActionConfig actionConfig)调用Action中对应的方法为:

1 Method method = null;
2             try {
3                 method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);
4             }
5   
6 if (!methodCalled) {
7                 methodResult = method.invoke(action, new Object[0]);//执行该方法
8             }

    创建Action: createAction(Map<String, Object> contextMap)

1 action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
2 //...
3 if (actionEventListener != null) {
4             action = actionEventListener.prepare(action, stack);
5         }

 

  

2.5 ActionProxy:怎么找到Action:存放actionName 和ActionInvocation对象。在ActionInvocation对象的初始化时创建Action:init(ActionProxy proxy)  中调用createAction(contextMap); struts中默认的实现类是StrutsActionProxy

 2.6 ObjectFactory   

ObjectFactory is responsible for building the core framework objects. Users may register their own implementation of the ObjectFactory to control instantiation of these Objects.

This default implementation uses the buildBean method to create all classes (interceptors, actions, results, etc).

     buildBean(config.getClassName(), extraContext)这个方法做的事情很简单:用ClassLoader加载classname所对应的class,extraContext这个参数没有用到。

 

2.7 ConfigurationManager - central for XWork Configuration management, including its ConfigurationProvider.

2.8 ConfigurationProvider interface describes the framework's configuration. By default, the framework loads its configurations via an xml document by using the StrutsXmlConfigurationProvider.

 

3、简单步骤

客户端提起一个(HttpServletRequest)请求,如上文在浏览器中输入”http://localhost:8080/TestMvc/add.action”就是提起一个(HttpServletRequest)请求。

  1. 请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
  2. FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter

    其代码如下:

    1. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException ...{
    2.         HttpServletRequest request = (HttpServletRequest) req;
    3.         HttpServletResponse response = (HttpServletResponse) res;
    4.         ServletContext servletContext = filterConfig.getServletContext();
    5.         // 在这里处理了HttpServletRequest和HttpServletResponse。
    6.         DispatcherUtils du = DispatcherUtils.getInstance();
    7.         du.prepare(request, response);//正如这个方法名字一样进行locale、encoding以及特殊request parameters设置
    8.         try ...{
    9.             request = du.wrapRequest(request, servletContext);//对request进行包装
    10.         } catch (IOException e) ...{
    11.             String message = "Could not wrap servlet request with MultipartRequestWrapper!";
    12.             LOG.error(message, e);
    13.             throw new ServletException(message, e);
    14.         }
    15.                 ActionMapperIF mapper = ActionMapperFactory.getMapper();//得到action的mapper
    16.         ActionMapping mapping = mapper.getMapping(request);// 得到action 的 mapping
    17.         if (mapping == null) ...{
    18.             // there is no action in this request, should we look for a static resource?
    19.             String resourcePath = RequestUtils.getServletPath(request);
    20.             if ("".equals(resourcePath) && null != request.getPathInfo()) ...{
    21.                 resourcePath = request.getPathInfo();
    22.             }
    23.             if ("true".equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT)) 
    24.                     && resourcePath.startsWith("/webwork")) ...{
    25.                 String name = resourcePath.substring("/webwork".length());
    26.                 findStaticResource(name, response);
    27.             } else ...{
    28.                 // this is a normal request, let it pass through
    29.                 chain.doFilter(request, response);
    30.             }
    31.             // WW did its job here
    32.             return;
    33.         }
    34.         Object o = null;
    35.         try ...{
    36.             //setupContainer(request);
    37.             o = beforeActionInvocation(request, servletContext);
    38. //整个框架最最核心的方法,下面分析
    39.             du.serviceAction(request, response, servletContext, mapping);
    40.         } finally ...{
    41.             afterActionInvocation(request, servletContext, o);
    42.             ActionContext.setContext(null);
    43.         }
    44.     }
    45. du.serviceAction(request, response, servletContext, mapping);
    46. //这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
    47. public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) ...{ 
    48.         HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());  //实例化Map请求 ,询问ActionMapper是否需要调用某个Action来处理这个(request)请求
    49.         extraContext.put(SERVLET_DISPATCHER, this); 
    50.         OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY); 
    51.         if (stack != null) ...{ 
    52.             extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack)); 
    53.         } 
    54.         try ...{ 
    55.             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext); 
    56. //这里actionName是通过两道getActionName解析出来的, FilterDispatcher把请求的处理交给ActionProxy,下面是ServletDispatcher的 TODO: 
    57.             request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack()); 
    58.             proxy.execute(); 
    59.          //通过代理模式执行ActionProxy
    60.             if (stack != null)...{ 
    61.                 request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack); 
    62.             } 
    63.         } catch (ConfigurationException e) ...{ 
    64.             log.error("Could not find action", e); 
    65.             sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e); 
    66.         } catch (Exception e) ...{ 
    67.             log.error("Could not execute action", e); 
    68.             sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); 
    69.         } 
    FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。
  3. ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类.
    如上文的struts.xml配置
    1. <?xml version="1.0" encoding="GBK"?>
    2.  <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
    3.  <struts>
    4.      <include file="struts-default.xml"/>
    5.      <package name="struts2" extends="struts-default">
    6.          <action name="add" 
    7.              class="edisundong.AddAction" >
    8.              <result>add.jsp</result>
    9.          </action>    
    10.      </package>
    11.  </struts>
    如果提交请求的是add.action,那么找到的Action类就是edisundong.AddAction。
  4. ActionProxy创建一个ActionInvocation的实例,同时ActionInvocation通过代理模式调用Action。但在调用之前ActionInvocation会根据配置加载Action相关的所有Interceptor。(Interceptor是struts2另一个核心级的概念)

    下面我们来看看ActionInvocation是如何工作的:

    ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口, 而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。

    Interceptor 的调度流程大致如下:
    1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。
    2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。

    Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。
    那么什么是拦截器。
    拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。)
    拦截器的例子这里就不展开了。
    struts-default.xml文件摘取的内容:
    1. < interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" /> 
    2. < interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" /> 
    3. < interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" /> 
    4. < interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" /> 
    5. < interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" /> 
    6. < interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> 
    7. < interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" /> 
    8. < interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" /> 
    9. < interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" /> 
    10. < interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" /> 
    11. < interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" /> 
    12. < interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" /> 
    13. < interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" /> 
    14. < interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" /> 
    15. < interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" /> 
    16. < interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" /> 
    17. < interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" /> 
    18. < interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" /> 
    19. < interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" /> 
    20. < interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" /> 
    21. < interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" /> 
    22. < interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" /> 
    23. < interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" /> 
    24. < interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" /> 
    25. < interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" /> 
    26. < interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" /> 
    27. < interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" /> 
    28. < interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /> 
    一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。如上文中将结构返回“add.jsp”,但大部分时候都是返回另外一个action,那么流程又得走一遍………

  总结:

  Struts2的工作流就只有这7步,比起Struts1简单了很多(本人能力有限,struts2更多的东西现在还看不明白)。网上有很多很多的关于.net和java的比较之类的文章,可是有几个作者是真正用过java和.net的呢?更多的评论都是人云亦云,想当然的评论java和.net。作为技术人千万不要屁股决定脑袋,关于web的设计模式上.net也不是那么一无是处,java也不是那么完美无缺

分享到:
评论

相关推荐

    深入浅出Struts2(附源码)

    本书是广受赞誉的Struts 2优秀教程,它全面而深入地阐述了Struts 2的各个特性,并指导开发人员如何根据遇到的问题对症下药,选择使用最合适的特性。作者处处从实战出发,在丰富的示例中直观地探讨了许多实用的技术,...

    深入浅出Struts 2 .pdf(原书扫描版) part 1

    2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例 26 2.5.1 部署描述文件和Struts配置文件 27 2.5.2 动作类 28 ...

    struts增加学生

    使用struts增加学生,用于描述简单的流程分析

    用Struts建立MVC应用的介绍

    1.Model1和Model2简介2.Struts的结构和处理流程简介3.利用Struts框架开发MVC系统要做的工作4.可供参考的例子参考资料关于作者1.Model1和Model2简介我们在开发Web应用时经常提到的一个概念是Model1/Model2,那么...

    Struts in Action中文版

    2. 深入 STRUTS架构..................................................................................37 2.1. 随便谈谈......................................................................................

    struts in Action

    2. 深入STRUTS 架构..................................................................................37 2.1. 随便谈谈.......................................................................................

    模拟银行存储管理系统 - 毕业设计源码

    2.1.1 Struts2框架技术 3 2.2.2 Hibernate框架技术 4 2.3 开发工具介绍 5 2.3.1 MyEclipse介绍 5 2.3.2 MySQL5.0介绍 5 3 需求分析 6 3.1 可行性分析 6 3.2 功能需求 6 3.3 性能需求 7 3.4 数据需求 7 3.5 数据字典 ...

    模拟银行存储管理系统 - 毕业设计论文

    2.1.1 Struts2框架技术 3 2.2.2 Hibernate框架技术 4 2.3 开发工具介绍 5 2.3.1 MyEclipse介绍 5 2.3.2 MySQL5.0介绍 5 3 需求分析 6 3.1 可行性分析 6 3.2 功能需求 6 3.3 性能需求 7 3.4 数据需求 7 3.5 数据字典 ...

    J2EE应用开发详解

    124 8.5.2 拦截器的实现原理 124 8.5.3 Struts2的内置拦截器 124 8.5.4 拦截器的配置和使用 125 8.5.5 自定义拦截器 126 8.6 一个简单的Struts2应用 130 8.7 小结 140 第9章 JSF 141 9.1 JSF技术简介 141 9.1.1 JSF...

    【计算机软件毕业设计】二手车交易平台的分析、设计与实现文献综述1.doc

    Struts的优势: 1、表现欲逻辑分离,使开发流程和架构更加合理; 2、Struts为系统开发人员提供了充分的扩展机制,维护扩展比较方便; 3、业界"标准",学习资源丰富,HTML标签优秀。 当然,Struts也有它的缺点: 1、...

    Java语言基础下载

    Struts如何实现Model 2, MVC 639 Struts 控制流 639 Struts framework的工作原理和组件 642 Struts ActionServlet控制器对象 642 Struts Action Classes 642 搞定Action对象 643 处理异常 643 Action的分类 643 ...

    java面试题

    59. 请对以下在J2EE中常用的名词进行解释(或简单描述) 40 59.1. web 容器 40 59.2. EJB容器 40 59.3. JNDI 40 59.4. JMS 41 59.5. JTA 41 59.6. JAF 41 59.7. RMI/IIOP 41 60. JAVA语言如何进行异常处理,关键字:...

    Spring面试题

    Struts的工作流程: 在web应用启动时就会加载初始化ActionServlet,ActionServlet从 struts-config.xml文件中读取配置信息,把它们存放到各种配置对象 当ActionServlet接收到一个客户请求时,将执行如下流程. -(1)检索和...

    大数据培训课程安排.pdf

    主要技术包括:Hibernate、Spring、SpringMVC、log4j slf4j 整合、myBatis、struts2、Shiro 、redis、流程引擎activity, 爬 ⾍技术nutch,lucene,webService CXF、Tomcat集群和热备 、MySQL读写分离 4. 描述如下:...

    最新Java面试宝典pdf版

    6、请对以下在J2EE中常用的名词进行解释(或简单描述) 129 7、如何给weblogic指定大小的内存? 129 8、如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 129 9、如何启动时不需输入用户名与密码? 130 10、...

    Java面试宝典2010版

    6、请对以下在J2EE中常用的名词进行解释(或简单描述) 7、如何给weblogic指定大小的内存? 8、如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 9、如何启动时不需输入用户名与密码? 10、在weblogic管理制...

Global site tag (gtag.js) - Google Analytics