Spring Boot学习----拦截器
Spring Boot 拦截器
定义拦截器
定义拦截器,只需要实现 HandlerInterceptor
接口。该接口中有三个方法: preHandle(……)
、postHandle(……)
和 afterCompletion(……)
。
preHandle(……)
方法:该方法的执行时机是,当某个url 已经匹配到对应的Controller 中的某个方法,且在这个方法执行之前。所以preHandle(……)
方法可以决定是否将请求放行,这是通过返回值来决定的,返回true 则放行,返回false 则不会向后执行。
postHandle(……)
方法:该方法的执行时机是,当某个url 已经匹配到对应的Controller 中的某个方法,且在执行完了该方法,但是在DispatcherServlet 视图渲染之前。所以在这个方法中有个ModelAndView 参数,可以在此做一些修改动作。
afterCompletion(……)
方法:顾名思义,该方法是在整个请求处理完成后(包括视图渲染)执行,这时做一些资源的清理工作,这个方法只有在preHandle(……)
被成功执行后并且返回true 才会被执行。
- 自定义拦截器。
public class MyInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String methodName = method.getName();
logger.info("====拦截到方法:{}====", methodName);
// 返回true才会继续执行,返回false则取消当前请求
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.info("执行完方法之后进执行(Controller方法调用之后),但是此时还没进行视图渲染");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.info("整个请求都处理完咯,DispatcherServlet也渲染了对应的视图咯,此时我可以做一些清理的工作了");
}
}
配置拦截器
在addInterceptors
方法来实现拦截器的配置。但是在
@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
在该配置中重写 addInterceptors
方法,将我们上面自定义的拦截器添加进去,addPathPatterns
方法是添加要拦截的请求,这里我们拦截所有的请求。这样就配置好拦截器了,接下来写一个
@Controller
@RequestMapping("/interceptor")
public class InterceptorController {
@RequestMapping("/test")
public String test() {
return "hello";
}
}
解决静态资源被拦截问题
上文中已经介绍了拦截器的定义和配置,但是这样是否就没问题了呢?其实不然,如果使用上面这种配置的话,我们会发现一个缺陷,那就是静态资源被拦截了。可以在
也就是说,虽然
如何放开呢?除了在addInterceptors
方法外,还需要再重写一个方法:addResourceHandlers
,将静态资源放开:
/**
* 用来指定静态资源不被拦截,否则继承WebMvcConfigurationSupport这种方式会导致静态资源无法直接访问
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
这样配置好之后,重启项目,静态资源也可以正常访问了。如果你是个善于学习或者研究的人,那肯定不会止步于此,没错,上面这种方式的确能解决静态资源无法访问的问题,但是,还有更方便的方式来配置。
我们不继承addInterceptors
方法,将自定义的拦截器添加进去即可,如下:
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 实现WebMvcConfigurer不会导致静态资源被拦截
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
这样就非常方便了,实现
这两种方式都可以,具体他们之间的细节,感兴趣的读者可以做进一步的研究,由于这两种方式的不同,继承
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!