Struts2最新版(2.5.12)快速入门(四) struts2之拦截器(Interceptor)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37992075/article/details/77054099
一、初识拦截器
           1、拦截器原理
                   "拦截器"顾名即可思义,它是对action的请求做出拦截,然后处理访问到action之前相应的业务逻辑。其原理还是比较简单的,当请求到我们的action的时候,struts2会去查找配置文件,
                   或者配置的annotation根据找到的拦截器配置去实例相对应的拦截器对象,然后把所有对象组成一个拦截器栈,最后依次调用拦截器栈中的拦截器。
         2、拦截器应用场景

                   在实际开发中,比如我有这样一个业务逻辑,需要对某些页面只许让登录了的用户访问,那么我们就需要对这些页面所对应的action做一些判断,就如判断session里面是否为空,如果我们项目比较大的话就会造成大量的代码冗余,后期维护起来比较困难,假如要修改一些业务逻辑的话,那么代码全部都要改一遍,这是很蛋疼的事。所以我们的拦截器好处就出现了,他可以为很多action配置同一个拦截器,我们需要该业务逻辑代码时只需要在拦截器里面修改代码即可,这样岂不乐哉?
二、拦截器与过滤器(filter)
                  拦截器(Interceptor)和我们以前接触过的 过滤器(filter)特别相似,但他们仅仅是相似而已,其差异还是很大的
                    1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
                    2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
                    3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
                    4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
                    5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
                    6、执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。
三、拦截器的创建、配置与使用
             1、预设拦截器

                   struts2会给我们预设一些拦截器,常用的预设拦截器有:
                              1、 params :把请求参数设置到相应的Action的属性去的,并自动进行类型转换。
                              2、 chain:将前一个执行结束的Action属性设置到当前的Action中。
                              3、 execption:顾名思义,在抛出异常的时候,这个拦截器起作用。
                              4、 token:核对当前Action请求(request)的有效标识,防止重复提交Action请求 。
                              5、 tokenSession:扩展了token拦截器的功能,当提交无效的Action请求标识时,它会跳转回到第一次成功后的页面。
                              6、 fileUpload:拦截器:用来处理文件上传。
                              7: timer:记录ActionInvocation余下部分执行的时间,并做为日志信息记录下来,便于寻找性能瓶颈。
                              8: logger:在日志信息中输出要执行的Action信息 ,这样在调试的时候,就能很快的定位到这个对应的Action了。
                              这里就暂时只列出这么多,其他的预设拦截器可以随着后面的学习再慢慢展开。

              2、自定义拦截器的创建与配置

                    1、创建拦截器
                                   继承AbstractInterceptor抽象类,然后重写intercept抽象方法
                                         如下所示、
					package com.example.interceptor;
					import com.opensymphony.xwork2.ActionInvocation;
					import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
					public class LoginInterceptor extends AbstractInterceptor{
						//拦截器初始化时调用
						@Override
						public void init() { 
							super.init();
							System.out.println("=======login 初始化========");
						}						
						//拦截器销毁时调用
						@Override
						public void destroy() { 
							super.destroy();
							System.out.println("=======login 销毁========");
						}					
						//拦截后业务逻辑处理方法
						@Override
						public String intercept(ActionInvocation invocation) throws Exception { 
							
							System.out.println("=======login 拦截前========");
							//调用拦截器栈中下一个拦截器,如果没有拦截器就调用action,并记录返回值
							String result=invocation.invoke();
							System.out.println("=======login 拦截后========");
							return result;		
						}
					}
                      这样我们就完成了一个自定义拦截器的创建,那么这里面我们可以重写三个方法,其中 intercept方法我们是必须重写的,因为我们所有拦截后的业务逻辑都是在这个方法里面完成处理。当我们这个拦截器的业务逻辑处理完后,我们可以通过invocation参数的invoke()方法调用拦截器栈中的下一个拦截器,如拦截器栈中没有拦截器可以调用了,那么它就继续调用我们请求的action,然后记录返回值,并返回出去。

                     2、配置拦截器
                                   拦截器配好了后,我们还需在struts.xml中配置我们刚才创建的拦截器
                                           1、单个拦截器配置
					 <package name="basic-struts2" extends="struts-default"> 
						<interceptors>
							<interceptor name="LoginInterceptor" class="com.example.interceptor.LoginInterceptor"/> 
						</interceptors>
					 </package> 
2、配置拦截器栈
                     往往我们有个时候一个action需要配置不止一个拦截器,比如我们判断了权限拦截后,还要进行执行时间的记录,还要打印日志等等,那么我们一个action中就要配很多个拦截器,那么我们有了拦截器栈后,我们把需要进行业务逻辑处理的拦截器放到拦截器栈中就可以直接在action中配置我们的拦截器栈即可。拦截器栈中的拦截器执行顺序是由上而下执行

                              如下所示:我们配置一个登录权限的拦截器,和一个预设拦截器 logger 放到拦截器栈里面
					<interceptor-stack name="Login">
 						<interceptor-ref name="LoginInterceptor"></interceptor-ref>
 						<interceptor-ref name="logger"></interceptor-ref>
 					</interceptor-stack>

                    3、调用拦截器
                                调用拦截器有两种方法
                                         1、struts.xml里面调用拦截器、拦截器栈
						<action name="login" class="com.example.action.UserAction" method="login">
	 						<interceptor-ref name="Login"/>
							<!-- 注:name属性为拦截器栈的name的话,他就会执行拦截器栈里面的所有拦截器-->
	 						<result name="success">/index.jsp</result>
	 					</action>

                                         2、annotation中调用拦截器、拦截器栈
						package com.example.action;
						import org.apache.struts2.convention.annotation.Action;
						import org.apache.struts2.convention.annotation.InterceptorRef;
						import org.apache.struts2.convention.annotation.ParentPackage;
						import org.apache.struts2.convention.annotation.Result;
						  
						@ParentPackage("basic-struts2")
						public class UserAction { 						
							@Action(
									value="login",
									interceptorRefs={ @InterceptorRef("Login")},
									results={ @Result(name="success",location="/index.jsp")  }
									)
							 public String login(){
								 System.out.println("======login=======");
								 return "success";
							 }
						}
                         上一节教程中我们介绍了这个注解 @InterceptorRef,但并没有讲它的使用方法,其实挺简单的,它里面就一个value,value对应我们在struts.xml中配置的拦截器、拦截器栈的name。
                         注意:我们这个action类它要和我们在struts.xml中配置拦截器、拦截器栈所在的package要相对应,所以我们要给这个action类加一个Annotation @ParentPackage("basic-struts2"),这里面的value对应于struts.xml中<package>的name。

猜你喜欢

转载自blog.csdn.net/m0_37992075/article/details/77054099