java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后再之前或者之后加入某些操作。目前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不用深究,知道即可。。
一:拦截器的应用场景
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page VIEW)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开SESSION,在完成后关闭SESSION。
二:拦截器与过滤器的区别
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3、拦截器只能对ACTION请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问ACTION上下文、值栈里的对象,而过滤器不能访问。
5、在ACTION的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
- 定义拦截器
@Component //声明为springBoot的一个组件,但是并不能起作用,需要在springBoot的配置类中注入
public class TimeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("TimeInterceptor 进入 Controller 某个方法之前");
System.out.println("Controller Name:"+((HandlerMethod)handler).getBean().getClass().getName());
System.out.println("Controller Method Name:"+((HandlerMethod)handler).getMethod().getName());
request.setAttribute("startTime", new Date().getTime());
/**
* boolean 值: 确定了拦截器其余两方法是否执行
*/
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("TimeInterceptor 运行 Controller 某个方法时,方法抛出异常将不进入此方法");
long start = (long) request.getAttribute("startTime");
System.out.println("TimeInterceptor 处理时长为:"+ (new Date().getTime() - start));
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("TimeInterceptor 完成 Controller 某个方法");
long start = (long) request.getAttribute("startTime");
System.out.println("TimeInterceptor 处理时长为:"+ (new Date().getTime() - start));
}
}
- 注入拦截器
//spring boot 1.0 -2.0版本
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor);
}
}
//spring boot 2.0以上版本
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Bean
public MyWebMvcConfig getMyWebMvcConfig(){
MyWebMvcConfig myWebMvcConfig = new MyWebMvcConfig() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("alogin");
registry.addViewController("/login").setViewName("alogin");
registry.addViewController("/main.html").setViewName("dashboard");
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/login","/","/user/login");
}
};
return myWebMvcConfig;
}