一、什么是拦截器
拦截器是动态拦截Action调用的对象,它提供了一种机制,可以使开发者自定义在一个action的前后执行指定代码,也可以在一个action执行之前阻止其执行。
同时,拦截器还可以将通用的代码模块化并作为可重用的类(Struts2中的很多特性都是由拦截器来完成的)。
在面向切面编程中(AOP),拦截器用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些指定操作。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
二、应用场景
身份认证、身份授权、登陆校验、异常处理、日志处理等。
三、拦截器与过滤器的区别:
1.拦截器是基于java反射机制的,而过滤器是基于函数回调的;
2.拦截器不依赖于servlet容器,而过滤器依赖于servlet容器;
3.拦截器只对action起作用,而过滤器几乎可以对所有请求起作用;
4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能;
5.在action的生命周期里,拦截器可以多起调用,而过滤器只能在容器初始化时调用一次。
四、实现方式
在SpringMvc中,拦截器的实现主要通过以下几步:
1.编写拦截器类实现HandlerInterceptor接口,或继承HandlerInterceptorAdapter类
2.将拦截器注册进SpringMvc框架中
3.配置拦截器的拦截规则
五、拦截器中的3个方法
1.preHandler:在进入Handler方法之前执行此方法,适用于身份认证、身份授权、登陆校验等,比如:在身份认证时,判断到用户没有登陆,则不再向下执行,返回值为false,即可实现拦截,否则,返回true时,不执行拦截;
2.postHandler:进入Handler方法之后执行此方法,返回ModelAndView之前执行,适用场景从ModelAndView参数出发,比如:将公用的模型数据在这里传入到视图,也可以统一指定显示的视图等;
3.afterHandler:在执行Handler完成后执行此方法,适用于统一的异常处理、日志处理等。
六、实现步骤
1.自定义拦截器类
package com.ys.test;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
/**
* 在DispatcherServlet处理方法之前执行,一般用来做一些准备工作:比如日志,权限检查
* 如果返回false 表示被拦截,将不会执行处理方法
* 返回true继续执行处理方法
*/
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
System.out.println("执行preHandler..." + req.getRemoteHost() + req.getRemoteUser());
resp.sendRedirect("index.jsp");
return false;
}
/**
* 在处理方法执行之后执行,在DispatcherServlet处理方法之后执行,一般用来做一些清理工作
*/
@Override
public void postHandle(HttpServletRequest req, HttpServletResponse resp, Object handler, ModelAndView mv)
throws Exception {
System.out.println("执行postHandler...");
}
/**
* 在结果返回给客户端之前执行,一般用来释放资源
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("执行afterCompletion...");
}
}
2.注册和配置拦截器
可以通过实现WebMvcConfigurer接口来完成拦截器的配置,主要用到以下3个方法:
addInterceptor():添加拦截器,传入拦截器对象
addPathPatterns():添加需要拦截的请求路径,若为/demo/**表示将拦截/demo下所有请求
excludePathPatterns():排除不需要拦截的请求路径,以登录为例,进入登录页面的/login当然要排除
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Resource
private LoginInterceptor loginInterceptor;
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(MyInterceptor)// 增加要注册的拦截器类
.addPathPatterns("/**")// 添加拦截范围(拦截‘/’下的所有请求)
.excludePathPatterns("/login");// 排除某些请求(这些请求无需拦截)
}
// 其他配置...
}