介绍
Spring拦截器是AOP思想在Spring框架中的一种具体实现,用于处理Web请求和HTTP请求相关的横切关注点。
拦截器就是用来拦截指定的请求,在请求前、请求处理后做出一些响应的业务逻辑处理,或者在请求完成后做一些资源释放。
应用场景
Spring拦截器的主要应用场景包括但不限于以下几点:
- 记录日志:可以在拦截器中添加日志记录代码,记录用户访问哪些页面或者执行哪些操作。
- 权限验证:在用户进行某些敏感操作(如修改密码)之前,需要先进行身份验证。
- 性能监控:通过拦截器可以实现对系统性能的监控,例如记录方法的执行时间等。
- 数据转换:可以将一种数据格式转换成另一种,例如将传入的字符串转换成实体对象。
- 会话管理:可以在拦截器中启动或关闭会话。
- 异常处理:当出现异常时,可以在拦截器中捕获并进行处理,而不是让异常直接抛出。
- 防止重复提交:通过拦截器可以防止用户重复提交表单,避免数据重复。
- 数据权限过滤:根据用户的角色或权限,动态地对查询条件进行过滤,确保用户只能查看到他们有权查看的数据。
实现一个自定义拦截器
1.创建自定义拦截器类
创建一个类,实现HandlerInterceptor
接口或继承HandlerInterceptorAdapter
类。这个接口包括以下三个方法:
preHandle
: 在请求处理之前被调用,返回true
继续执行后续操作,返回false
将终止请求处理。postHandle
: 在请求处理后,视图渲染之前被调用。afterCompletion
: 在请求完成后,视图渲染完成后被调用。
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在控制器方法执行前执行的逻辑
System.out.println("MyHandlerInterceptor-preHandle");
return true; // 可以返回true表示继续执行后续拦截器和处理程序,返回false表示中止执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在控制器方法执行后视图渲染前执行的逻辑
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在视图渲染后执行的逻辑,通常用于清理资源
}
}
2.注册拦截器到Spring 容器中
创建一个WebMvcConfigurer
实现类,并覆盖addInterceptors
方法来注册拦截器。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyHandlerInterceptor())
.addPathPatterns("/**") // 拦截路径
.excludePathPatterns("/login");// 放行路径
}
}
案例演示
使用拦截器记录请求日志
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在控制器方法执行前执行的逻辑
String requestURI = request.getRequestURI();
String method = request.getMethod();
String serverName = request.getServerName();
log.info("--------------------------------");
log.info("请求路径:{} ",requestURI);
log.info("请求方法:{} ",method);
log.info("请求地址:{} ",serverName);
log.info("--------------------------------");
return true; // 可以返回true表示继续执行后续拦截器和处理程序,返回false表示中止执行
}