java拦截器详解

157 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

概念

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈 Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

原理

大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。

代码实现

定义拦截器

定义一个类,实现HandlerInterceptor接口即可

@Component //注意当前类必须受Spring容器控制

//定义拦截器类,实现HandlerInterceptor接口

public class ProjectInterceptor implements HandlerInterceptor {



@Override

//原始方法调用前执行的内容

//返回值类型可以拦截控制的执行,true放行,false终止

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

  System.out.println("preHandle..."+contentType);
  
  return true;
  
}


@Override

//原始方法调用后执行的内容

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  System.out.println("postHandle...");
  
  
}


@Override

//原始方法调用完成后执行的内容

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

  System.out.println("afterCompletion...");
  
  }
  
}


配置加载拦截器

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
  @Autowired
  private ProjectInterceptor projectInterceptor;

  @Override
  protected void addInterceptors(InterceptorRegistry registry) {
  //配置拦截器
  registry.addInterceptor(projectInterceptor)
  .addPathPatterns("/books","/books/*");
  }
}

 

使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强) 

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
  @Autowired
  private ProjectInterceptor projectInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
  //配置多拦截器
  registry.addInterceptor(projectInterceptor)
  .addPathPatterns("/books","/books/*");
  }
}

应用场景

1、日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。

2、权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。

3、性能监控:典型的是慢日志