原文链接:https://blog.csdn.net/kuishao1314aa/article/details/109777304
一、Interceptor定义:
拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制
1.拦截器(Interceptor)执行顺序:
1. 请求到达 DispatcherServlet
2. DispatcherServlet 发送至 Interceptor ,执行 preHandle
3. 请求达到 Controller
4. 请求结束后,postHandle 执行
2.拦截器(Interceptor)和过滤器(Filter)的执行顺序
过滤前->拦截前->Action处理->拦截后->过滤后
3.使用方法
1)预处理preHandle()方法
用户发送请求时,先执行preHandle()方法。会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则执行用户请求的url方法。
2)后处理postHandle()方法
调用了Service并返回ModelAndView,但未进行页面渲染,可以在这里继续修改ModelAndView
3)返回处理afterCompletion()方法
已经渲染了页面,在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
注:一般使用preHandle这个拦截器进行预处理,对url进行请求拦截
二、Spring Boot配置方式
1.自定义拦截器,需要继承HandlerInterceptorAdapter类
1 @Component 2 public class AuthorityInterceptor extends HandlerInterceptorAdapter { 3 private static final Logger logger = LoggerFactory.getLogger(AuthorityInterceptor.class); 4 5 @Override 6 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 7 logger.info("进入到拦截器中:preHandle() 方法"); 8 System.out.println(request.getServletPath()); 9 return true; 10 } 11 @Override 12 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 13 logger.info("进入到拦截器中:postHandle() 方法中"); 14 System.out.println(request.getRequestURI()); 15 } 16 17 @Override 18 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 19 logger.info("进入到拦截器中:afterCompletion() 方法中"); 20 System.out.println(request.getServletPath()); 21 } 22 }
2.注册拦截器,需要继承WebMvcConfigurerAdapter类
需要重写addInterceptors方法,这里是对根目录"/"进行拦截,可以指定拦截url请求目录
@Configuration public class InterceptorAdapterConfig extends WebMvcConfigurerAdapter { @Autowired private AuthorityInterceptor authorityInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { //注册自己的拦截器并设置拦截的请求路径 registry.addInterceptor(authorityInterceptor).addPathPatterns("/**"); super.addInterceptors(registry); } }
3.测试结果
1)用户请求的url如下所示:
2)发送请求,进入到拦截器
三、Spring 配置方式
注册拦截器,使用spring mvc来注册,替换上面的1.2步骤
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.vivo.finance.web.interceptor.AuthorityInterceptor" /> </mvc:interceptor> </mvc:interceptors>
四、对指定方法进行拦截或对某些方法不拦截
这里的注册监听器,自定义监听器写法和前面一致。
如果对url目录下所有的请求进行了监听,但需要对某些请求方法不进行拦截或单独拦截,可以采用自定义注解方式,对方法加上自定义注解,拦截器进行扫描,对出现过自定义注解的方法进行单独处理
1.自定义注解
目标为方法,仅在运行时有效LoginSuccess可以在定义中通过反射获取字段值,仅用注解可以不管
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LoginVerify { boolean LoginSuccess() default true; }
2.preHandle对自定义注解@LoginVerify进行拦截
preHandle对有@LoginVerify注解的方法进行单独处理
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info("进入到拦截器中:preHandle() 方法"); HandlerMethod handlerMethod=(HandlerMethod)handler; LoginVerify loginVerify=handlerMethod.getMethodAnnotation(LoginVerify.class); if (loginVerify!=null){ System.out.println(loginVerify.LoginSuccess()); logger.info("不需要对 @loginVerify注解方法 进行拦截"); }else { logger.info("对非@loginVerify注解方法 进行拦截处理"); System.out.println(request.getServletPath()); System.out.println(request.getParameter("id")); return true; } return true; }
3.自定义注解使用位置
将@LoginVerify注解施加到方法上即可
@LoginVerify(LoginSuccess=false) @RequestMapping("/test2") public String testConnection(){ System.out.println("test2"); return "test2"; }
4.实现结果
发送请求