Struts2学习教程之拦截器机制与自定义拦截器

所属分类: 软件编程 / java 阅读数: 16
收藏 0 赞 0 分享

前言

拦截器体系是Struts2框架的重要组成部分,不夸张的说,没有拦截器体系,也就没有这么好用的Struts2框架了。在Struts2框架中,大量的拦截器完成了很多基础的功能,比如,params拦截器负责解析HTTP请求的参数,并设置Action的属性;servlet-config拦截器直接将HTTP请求中的HttpServletRequest实例和HttpServletResponse实例传给Action;fileUpload拦截器则负责解析请求参数中的文件域,并将一个文件域设置成Action的三个属性......这一切的一切都是由内建的拦截器来完成的。所以,掌握了Struts2中拦截器的使用原理与方式,也就把握住了Struts2框架的“命脉”。

但是学习Struts2到现在,除了在web.xml中配置了一个StrutsPrepareAndExecuteFilter过滤器外,还没有接触其它的什么拦截器,那为什么我们的应用能够很好的运行呢?实际上,Struts2已经默认启用了大量通用的拦截器,只要配置Action的package继承了struts-default包,这些拦截器就会起作用。下面来看看Struts2内建的拦截器。

Struts2内建的拦截器

在Struts2框架中有很多内建的拦截器,这些拦截器几乎完成了Struts2框架70%的工作,包括解析请求参数,将请求参数赋值给Action属性等,Struts2这种灵巧的设计,很大程度上得益于拦截器的设计;当需要扩展Struts2功能时,只需要提供对应拦截器,并将它配置在Struts2容器中即可。

这些内建的拦截器以name-class对的形式配置在struts-default.xml文件中,其中name是拦截器名字,就是以后使用该拦截器的唯一标识;class则指定了该拦截器的实现类。对于这些内建的拦截器的详细介绍,请参见官方文档

配置拦截器

在Struts.xml文件中定义拦截器只需为拦截器类指定一个拦截器名,就完成了拦截器定义。定义拦截器使用<interceptor.../>,例如:

<!-- 通过指定拦截器名和拦截器实现类来定义拦截器 -->
<interceptor name="拦截器名" class="拦截器实现类">
  <param name="参数名">参数值</param>
</interceptor>

除此之外,还可以把多个拦截器连在一起组成拦截器栈,在拦截器中使用<interceptor-ref .../>来定义拦截器引用。例如:

<interceptor-stack name="拦截器栈一">
  <interceptor-ref name="拦截器一"/>
  <interceptor-ref name="拦截器二"/>
  ...
</interceptor-stack>

从程序结构上来看,拦截器栈由多个拦截器组成;但是从程序功能上来说,拦截器栈和拦截器是一样的,它们包含的方法都会在Action的execute方法执行之前自动执行。所以,我们完全可以把拦截器栈当成一个更大的拦截器。

由于拦截器栈和拦截器是一致的,所以拦截器栈中又可以包含拦截器栈,例如:

<interceptor-stack name="拦截器栈二">
  <interceptor-ref name="modelDriven"/>
  <interceptor-ref name="拦截器栈一"/>
</interceptor-stack>

使用拦截器

一旦定义了拦截器栈和拦截器后,就可以使用这个拦截器栈或拦截器来拦截Action了,拦截器的拦截行为将会在Action的execute方法执行之前被执行。

通过使用<interceptor-ref .../>元素可以在Action内使用拦截器,在Action中使用拦截器的配置语法与配置拦截器栈时引用拦截器的语法完全一样。例如:

<action name="login" class="com.jellythink.practise.LoginAction">
  <result name="error">/error.jsp</result>
  <result name="success">/welcome.jsp</result>
  <!-- 拦截器栈 -->
  <interceptor-ref name="defaultStack"/>
  <!-- 拦截器 -->
  <interceptor-ref name="test1"/>
  <!-- 带参数的拦截器 -->
  <interceptor-ref name="test2">
    <param name="key">动态参数</param>
  </interceptor-ref>
</action>

这样配置完成以后,在执行DownloadAction之前,这三个拦截器都会起作用。

配置默认拦截器

当配置一个包时,可以为其指定默认拦截器。一旦为某个包指定了默认的拦截器,如果该包中的Action没有显式指定拦截器,则默认的拦截器将会起作用。但是,一旦我们为该包中的Action显式应用了某个拦截器,则默认的拦截器不会起作用;如果该Action需要使用该默认拦截器,则必须手动配置该拦截器的引用。

只有当Action中没有显式应用拦截器时,该Action所在包的默认拦截器才会生效。

配置默认拦截器使用<default-interceptor-ref.../>元素,该元素作为<package.../>元素的子元素使用,为该包下的所有Action配置默认的拦截器。例如:

<default-interceptor-ref name="默认拦截器"/>

也可以为默认拦截器指定参数,例如:

<default-interceptor-ref name="默认拦截器">
  <param name="参数名">参数值</param>
</default-interceptor-ref>

在struts-default.xml文件中,配置了一个名为struts-default的抽象包,在该包中定义了名为defaultStack的默认拦截器引用。当我们定义的包继承struts-default包时,也继承了它的默认拦截器栈:defaultStack,这也意味着,如果我们不为Action显式地应用拦截器,则defaultStack拦截器栈会自动生效。

自定义拦截器

1>.添加一个类,让它继承AbstractInterceptor类,或者实现Interceptor接口

public class TimeInterceptor extends AbstractInterceptor {
/**
* 拦截器的核心方法intercept的返回值是一个字符串
*/
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
return "login";
}
}

2>.在struts.xml的package中添加interceptors子节点,并在它下面添加Interceptor节点

<package name="goods" namespace="/goods" extends="common-pkg">
<interceptors>
<interceptor name="timeInterceptor" class="com.wskj.struts2.interceptor.TimeInterceptor"></interceptor>
</interceptors>
</package>

3>.在想被拦截的action节点下添加子节点interceptor-ref

<action name="list_Category" class="com.wskj.struts2.controller.CategoryAction" method="list">
<interceptor-ref name="timeInterceptor"></interceptor-ref>
<result name="list" type="dispatcher">/pages/Category/list.jsp</result>
</action>

这篇文章对Stuts2中的核心——拦截器进行了一个初步的总结,在后面的文章中,我们会实现一个我们自己的拦截器,并将这篇文章中总结的知识点进行运用。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

Java数据类型的规则

这篇文章主要介绍了Java数据类型的规则的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring整合TimerTask实现定时任务调度

这篇文章主要介绍了Spring整合TimerTask实现定时任务调度的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解SpringMVC使用MultipartFile实现文件的上传

本篇文章主要介绍了SpringMVC使用MultipartFile实现文件的上传,本地的文件上传到资源服务器上,比较好的办法就是通过ftp上传。这里是结合SpringMVC+ftp的形式上传的,有兴趣的可以了解一下。
收藏 0 赞 0 分享

SpringMVC上传文件的三种实现方式

本篇文章主要介绍了SpringMVC上传文件的三种实现方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

本篇文章主要介绍了微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
收藏 0 赞 0 分享

浅析Java中的继承与组合

本文将介绍组合和继承的概念及区别,并从多方面分析在写代码时如何进行选择。文中通过示例代码介绍的很详细,有需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

利用反射获取Java类中的静态变量名及变量值的简单实例

下面小编就为大家带来一篇利用反射获取Java类中的静态变量名及变量值的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java启动线程的3种方式对比分析

这篇文章主要为大家对比分析了java启动线程的3种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SpringMVC上传和解析Excel方法

这篇文章主要介绍了SpringMVC上传和解析Excel方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

JAVA中String类与StringBuffer类的区别

这篇文章主要为大家详细介绍了JAVA中String类与StringBuffer类的区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多