一.首先我应该先要了解Struts2拦截器的执行原理
Struts 2的拦截器实现相对简单。当请求到达Struts2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配 置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。事实上,我们之所以能够如此灵活地使用拦截器,完全归功于“动态代理”的使用。动态代理是代理对象根据客户的需求做出不同的处理。对于客户来说,只要知道一个代理对象就行了。
那Struts2中,拦截器是如何通过动态代理被调用的呢? 当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute()或指定的方法,并在 struts.xml中查找与该Action对应的拦截器。如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;如果没有对应的拦截 器则执行Action的方法。其中系统对于拦截器的调用,是通过ActionInvocation来实现的。
Struts2的工作原理图:
一.通过实例来实现Struts2拦截器的功能
1.简单的自定义一个拦截器的步骤:
(1)编写拦截器类,需要实现Interceptor接口或者继承AbstractInterceptor类。
(2)修改配置文件加上拦截器信息,并完成注册使用(此处省略添加Jar包和创建Web项目的步骤)。
下面通过实例来演示效果,首先是Action组件,代码如下。
定义拦截器组件,代码入下。
最后的重点,在struts.xml文件中进行配置,代码入下。
至此,一个简单的拦截器组件配置完成。线面我们运行程序查看结果,打开浏览器输入地址,注意:直接访问Action即可,在控制台输入如图所示。
可以看出拦截器的拦截方法在Action方法执行之前执行了。接下来我们修改一下代码,再来研究一下执行的细节效果。在拦截器中的拦截方法中修改如下。
同时在index.jsp中加入一行Java代码。
再次运行结果,控制台的输出结果如下。
代码语言:javascript复制arg0.invoke() 就是通知struts2接着干下面的事情 比如 调用下一个拦截器 或 执行下一个Action 拦截器的值返回值要么代表继续拦截 要么是success等一些类Action类提供的静态量 它会根据这个值去到相应的页面
分析控制台输出结果:可以发现拦截器、Action和JSP页面执行的过程,首先请求进入拦截器,执行完成拦截器的功能,调用ActionInvocation对象的invoke方法,从而进入到Action中执行Action的处理方法,接着根据配置转入到相应的View(index.jsp)页面,执行完JSP页面代码后,再次回到拦截中,执行剩下的代码。这里值得注意的是:拦截器中的invoke方法执行完毕后,如果还有后续代码,当视图层执行完毕后,还会接着回来执行后面的代码,这也是前面说的为什么拦截器会在Action的执行前和执行后都会运行。
接着我们来配置两个拦截器,进一步理解多个拦截器是如何系统工作的。在上述的案例中,我们再新增一个拦截器Interceptor2,这次实现Interceptor接口,代码如下。
接下来就是配置文件的内容,增加了一个新的拦截器,代码入下(配置方法和案例一相同)。
我们再次运行程序,控制台输出结果如下。
这次控制台输出的结果是两个拦截器依次拦截的效果,大家仔细分析,可以看出多个拦截器的执行也遵循前面的案例规则,即拦截器会依次执行,当执行完JSP页面后会再次进入拦截器里面执行后续的剩下的代码。需要大家注意的是:再回到拦截器里面执行的时候,执行的顺序是倒过来的。最后大家记住:拦截器只是拦截请求Action的组件,对于请求的JSP组件,拦截器是不会工作的!
2.我对拦截器栈的理解
在前面的案例中我们已经看到了定义拦截器的代码。接下来仔细研究如何配置拦截器。首先我们已经知道了配置拦截器所需要的以下两个元素。
(1)通过<interceptor…/>元素来定义拦截器
(2)在Action中通过<interceptor-ref…/>元素来使用拦截器。
如果自己写的拦截器比较多,而且每个拦截器都要在Action中依次引用来使用的话,配置起来就比较麻烦了。我们可以利用拦截器栈的概念来进行改进,代码如下。
我们再次运行程序,控制台输出结果如下(和上述案例运行结果一致)。
上述配置中在interceptors元素中使用interceptor-ref元素定义拦截器栈,name属性指定拦截器的名称,在栈中依然使用interceptor-ref元素指定引用拦截器。定义好拦截器栈后,在Action中直接引用拦截器栈,从而简化配置。值得注意的是:拦截器栈定义的时候是可以嵌套的,也就是一个拦截器栈里面也还可以引用其他的拦截器栈。
最后,如果配置文件中大多数Action都想用相同的拦截器或拦截器栈,建议定义默认的拦截器引用,使用<default-interceptor-ref/>元素来定义,其中name属性依然是指定引用拦截器或者拦截器栈的名称,那么配置文件会是如下的形式。
3.Struts2常用的拦截器
你打开struts-default.xml这个文件,找到拦截器的定义,这里面的都是常用的。
这里我就不一一介绍了,如果大家想详细了解可以给我私信或者通过百度的方式了解一下。
4.Struts2默认拦截器栈
Struts2对于开发中要经常用到的功能,给大家定义了一个非常重要的拦截器栈:defaultStack拦截器栈。defaultStack拦截器栈组合了多个拦截器,这些拦截器经过精心的设计和挑选,能够满足大多数Web应用程序的需求,我们只要是在定义包的过程中继承struts-default包,那么defaultStack拦截器将会是所有Action默认的拦截器引用。
例如:
Struts2为我们提供了如此丰富的拦截器,基本上开发时常用的功能都够用了。所以使用它能够大大提高我们的开发效率。最后一个大家要注意的事项:一旦在struts.xml中配置了自己的拦截器,并且使用了,那么系统将不会调用默认的拦截器栈(defaultStack),系统提供的所有功能也将失效。所以一般来说,我们会把自己的拦截器栈和默认的拦截器进行再整合,形成一个新的拦截器栈,将这个新的拦截器栈配成默认的。这样就可以让Struts2即执行开发人员定义的拦截器又拥有系统默认的所有功能。
好啦,我今天的博客完成啦,欢迎大家继续关注,我会持续更新作品的。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184868.html原文链接:https://javaforall.cn