最近离职在家,闲来无事,就想把最近工作一年用到的技术和资料整理一下。本来打算写成word文档,但又转身一想,写成博客放在网上供更多人分享,岂不跟好。而且在网上放的东东更具有安全性。想起以前因为硬盘坏掉而丢失是数据,心中就痛。什么是struts2
Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。(来自百度百科)
总的来说strtus2降低了对jsp/servlet的耦合,也减少对web容器的依然。使对web层的开发可以完全脱离servlet。可以像操作一个普通的java类一个来操作一个web页面控制器。struts2中的Action可以是一个简单的POJO类,不用继承任何类或实现接口,这样大大的加大了action编写的自由度。
Struts2的工作流程
此图是struts2的结构流程图
从图可以看出,一个请求在Struts2框架中的处理大概分为以下几个步骤:
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过Configuration Manager询问框架的配置文件(struts.xml),找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper。
然而从2.1.3开始,核心过滤器变成strutsprepareandexecutefilter抛弃了原来的FilterDispatcher和ActionContextCleanUp。struts2源码分析
<!-- 配置Struts2的过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Struts2建议,在对Struts2的配置尚不熟悉的情况下,将url-pattern配置为/*,这样该过滤器将截拦所有请求。StrutsPrepareAndExecuteFilter实现了StrutsStatics和Filter两接口StrutsStatics并没有定义业务方法,StrutsStatics并没有定义业务方法,只定义了若干个常量。Struts2对常用的接口进行了重新封装,比如HttpServletRequest、HttpServletResponse、HttpServletContext等
如图在web容器启动时,就会初始化StrutsPrepareAndExecuteFilter调用它的init(FilterConfig filterConfig)方法,创建Dispatcher类的对象,并将配置的一些参数传递给它Dispatcher dispatcher = init.initDispatcher(config)并负责Action的执行。在Dispatcher.init()方法中加载struts-default.xml,struts-plguin.xml struts.xml等配置文件。因为它们同在一个dtd约束下,如果文件中出现相同的配置后者会覆盖前者。
当用户向Struts2发送请求时,会调用StrutsPrepartAndExecuteFileter的doFilter()方法自动调用,这个方法非常关键。首先,Struts2对请求对象进行重新包装,负责所有请求的编码和一些本地化操作。创建ActionContext和初始化本地线程,在创建ActionContext之前创建StactkValue并把请求和ServletContext放入值栈中。