拦截器的特性
- 拦截器可以拦截controller请求
- 拦截器可以中断请求轨迹
- 请求之前如果该请求配置了拦截器,则请求会先经过拦截器,拦截器放行之后执行请求的controller,controller执行完成之后会回到拦截器继续执行拦截器中的代码
拦截器开发
1、编写拦截器类,实现 HandlerInterceptor 接口
preHandler 预先处理方法 最先执行方法 返回值:布尔类型 true 放行请求 false 中断
postHandler 过程中处理: controller返回之后回到posthandler这个方法执行,执行完成这个方法开始响应浏览器
afterCompletion 最后完成:响应结束之后会执行拦截器中的这个方法
下面我写了两个拦截器
package com.peko.interceptor.interceptor;
import com.peko.interceptor.controller.MyController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Peko
*/
public class MyInterceptor1 implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
/**
*
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("=========1========");
//true 放行 false 中断
return true;
}
/**
*
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @param modelAndView 模型和视图 当前请求访问方法的modelandview
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
logger.info("=========2========");
}
/**
* 这个方法相当于 finally{}代码块,即无论请求是否有问题都会执行
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @param ex 如果控制器出现异常时异常对象
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
logger.info("=========3========");
}
}
package com.peko.interceptor.interceptor;
import com.peko.interceptor.controller.MyController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Peko
*/
public class MyInterceptor2 implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
/**
*
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("=========4========");
//true 放行 false 中断
return true;
}
/**
*
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @param modelAndView 模型和视图 当前请求访问方法的modelandview
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
logger.info("=========5========");
}
/**
* 这个方法相当于 finally{}代码块,即无论请求是否有问题都会执行
* @param request
* @param response
* @param handler 当前请求的控制器的方法对象
* @param ex 如果控制器出现异常时异常对象
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
logger.info("=========6========");
}
}
2、配置拦截器,实现 WebMvcConfigurer接口
类 implements WebMvcConfigurer{
//覆盖配置拦截器方法
1.使用哪个拦截器
2.拦截器拦截请求
3.排除哪些请求
}
package com.peko.interceptor.config;
import com.peko.interceptor.interceptor.MyInterceptor1;
import com.peko.interceptor.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author Peko
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor1()) //指定拦截器
.addPathPatterns("/**") //拦截所有
.order(1); //指定拦截器执行顺序
registry.addInterceptor(new MyInterceptor2()) //指定拦截器
.addPathPatterns("/**") //拦截所有
.order(2); //指定拦截器执行顺序
}
}
3、Controller
package com.peko.interceptor.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Peko
*/
@RestController
@RequestMapping("demo")
public class MyController {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
@RequestMapping("demo")
public String demo(){
logger.info("OK!11");
return "OK!";
}
}
4、运行项目,访问 http://localhost:8082/demo/demo,打印日志
2021-10-08 17:46:49.782 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========1========
2021-10-08 17:46:49.782 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========4========
2021-10-08 17:46:49.782 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : OK!11
2021-10-08 17:46:49.783 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========5========
2021-10-08 17:46:49.784 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========2========
2021-10-08 17:46:49.784 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========6========
2021-10-08 17:46:49.784 INFO 6796 --- [nio-8082-exec-4] c.p.interceptor.controller.MyController : =========3========
多个拦截器的执行顺序
当配置了多个拦截器时,多个拦截器会以栈的方式执行
例如:现在配置了两个拦截器 1-preHandle1、2-postHandle1、3-afterCompletion1 4-preHandle2、5-postHandle2、6-afterCompletion2
则执行顺序威: 1 4 5 2 6 3
gitee项目地址:https://gitee.com/ShyHour/interceptor