Struts与webwork已合并为struts2框架,struts2框架良好的扩展性与简洁性使其适用于任何规模的企业web程序的开发。本节我们将向大家展示struts2框架的结构
在struts2中一个请求的生存周期:
1. 用户发送请求 : 用户为访问资源向服务器发送请求。
2. FilterDispatcher决定适当的action : FilterDispatcher接受请求然后决定调用适当的action
3. 调用拦截器 : 配置拦截器来应用常用的功能如工作流,验证,文件上传等,都是自动应用于请求的。
4. action的执行 : 然后action将被执行来调用诸如存储数据、检索数据之类的数据库相关操作。
5. 呈递输出 : 结果呈递到输出
6. 返回请求 : 请求通过拦截器按照相反的顺序返回,返回的请求可以允许我们执行一些清理或额外的处理
7. 向用户展示结果 : 控制权最终回归到输出结果至用户浏览器的Servlet容器
图:struts2中请求流程的高度概括
Struts2 结构 :
Struts2框架拥有良好的简洁性与易扩展的前端控制器,基于很多像Java Filters, Java Beans, ResourceBundles, XML等标准技术。
对于模型层来说,struts2可以使用任何数据访问技术,像JDBC, EJB, Hibernate等,对于视图层来说,struts2可以与JSP, JTL, JSF, Jakarta Velocity Engine, Templates, PDF, XSLT等整合。
异常处理 :
Struts2允许我们定义异常处理器和拦截器
l 异常处理器
异常处理器允许我们定义基于局部和全局的异常处理程序.struts2捕获到异常后会将恰当的信息和异常的详情显示在我们指定的页面上。
l 拦截器
拦截器详细说明了一个action的请求流程的生存周期.配置的拦截器对请求实现了一些常用的功能如工作流,验证等.
Struts2 结构
下图描述了struts2的结构,同时展示了初始请求如何转到像Tomcat这类的serlet容器,然后通过过滤链
图 : struts2 结构
过滤器链包括 :
l Action ContextCleanUp filter :
Action ContextCleanUp filter是可选的,当与其他的技术如SiteMash插件整合的时候会很有帮助.
l FilterDispatcher :
接着FilterDispatcher被调用,然后依次调用ActionMapper来决定是不是要引用一个action.如果一个action需要被引用, FilterDispatcher将托付ActionProxy来管理
l ActionProxy :
Action代理能从初始化自struts.xml的配置文件管理器那得到帮助,接着ActionProxy创建一个实现了命令模式的ActionInvocation,ActionInvocation在处理的过程中调用拦截器(如果配置了)然后调用Action ActionInvocation寻找恰当的结果,然后结果呈递到JSP或者模板上。
之后拦截器再按照相反的顺序执行了一遍,最终响应通过配置在web.xml中的过滤器返回.如果配置了ActionContextCleanUp filter, FilterDispatcher不会清理线程局部ActionContext.如果ActionContextCleanUp filter没有被配置, FilterDispatcher会清理所有当前的线程局部.
对于 filter:
使用方法是创建一个类 XXXFilter实现 Filter接口,并在该类中的 doFilter方法中声明过滤规则,然后在配置文件web.xml中声明他所过滤的路径
对于 Interceptor
使用方法也是创建一个类 XXXInterceptor实现 Interceptor 接口 ,在该类中 intercept方法写过滤规则,不过与strut.xml结合使用。
另外一些不同:
1. filter基于回调函数, doFilter方法就是回调函数,而 interceptor则基于java本身的反射机制 ,这是两者最本质的区别。
2. filter是依赖于 servlet容器的,即只能在 servlet容器中执行。而 interceptor与 servlet容器无关。
3. Filter的过滤例外一般是在加载的时候在 init方法声明 ,而 Interceptor可以通过在 xml声明是 guest请求还是 user请求来辨别是否过滤
前段时间参与一个项目,过滤器用的是 Interceptor 觉得比以前用的 Filter 好用很多,现在拿出来比较一下
Filter
该过滤器的方法是创建一个类 XXXFilter 实现此接口,并在该类中的 doFilter 方法中声明过滤规则,然后在配置文件 web.xml 中声明他所过滤的路径
<filter>
<filter-name>XXXFilter</filter-name>
<filter-class>
com.web.util.XXXFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>XXXFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
Interceptor
该过滤器的方法也是创建一个类 XXXInterceptor 实现此接口 , 在该类中 intercept 方法写过滤规则,不过它过滤路径的方法和 Filter 不同,它与 strut.xml 结合使用,
创建一个 strus.xml 的子配置文件 struts-l99-default.xml ,它继承与 struts2 的 struts-default ,此配置文件是其他子配置文件的父类,只要是继承与该文件的配置文件所声明的路径都会被它过滤 如下
<package name="XXX-default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="authentication" class="com.util.XXXInterceptor" />
<interceptor-stack name="user">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="authentication" />
</interceptor-stack>
<interceptor-stack name="user-submit">
<interceptor-ref name="user" />
<interceptor-ref name="token" />
</interceptor-stack>
<interceptor-stack name="guest">
<interceptor-ref name="defaultStack" />
</interceptor-stack>
<interceptor-stack name="guest-submit">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="token" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="user" />
</package>
比较一 ,filter 基于回调函数,我们需要实现的 filter 接口中 doFilter 方法就是回调函数,而 interceptor 则基于java本身的反射机制 , 这是两者最本质的区别。
比较二 ,filter 是依赖于 servlet 容器的,即只能在 servlet 容器中执行,很显然没有 servlet 容器就无法来回调doFilter 方法。而 interceptor 与 servlet 容器无关。
比较三, Filter 的过滤范围比 Interceptor 大 ,Filter 除了过滤请求外通过通配符可以保护页面,图片,文件等等,而Interceptor 只能过滤请求。
比较四, Filter 的过滤例外一般是在加载的时候在 init 方法声明 , 而 Interceptor 可以通过在 xml 声明是 guest 请求还是 user 请求来辨别是否过滤。