SpringBoot之HandlerInterceptor拦截器

本文详细介绍了Spring MVC框架中的拦截器(Interceptor)概念,包括其实现方式及应用场景,如登录拦截、权限校验等。同时,阐述了三种主要的拦截器方法:preHandle用于预处理,postHandle用于后处理,afterCompletion则用于资源清理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#HandlerInterceptor简介
拦截器我想大家都并不陌生,最常用的登录拦截、或是权限校验、或是防重复提交、或是根据业务像12306去校验购票时间,总之可以去做很多的事情。

定义一个Interceptor 非常简单方式也有几种,我这里简单列举两种
1、类要实现Spring 的HandlerInterceptor 接口

2、类继承实现了HandlerInterceptor 接口的类,例如 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter

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

	void postHandle(
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception;

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

preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView (这个博主就基本不怎么用了);
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);

### Spring Boot 中使用 HandlerInterceptor 实现拦截器Spring Boot 应用程序中,通过实现 `HandlerInterceptor` 接口可以轻松定义和配置拦截器。此接口提供了三个主要的方法来控制请求处理的不同阶段。 #### 方法概述 - **preHandle**:该方法会在控制器方法调用之前执行。返回 true 表示继续流程;false 则会中断后续操作并立即结束当前请求[^5]。 - **postHandle**:当控制器完成业务逻辑但视图尚未解析时触发。允许修改模型数据或更改使用的视图名称。 - **afterCompletion**:在整个请求完成后被调用,在这里可以清理资源或者记录日志等操作. #### 定义拦截器类 为了创建一个简单的登录验证拦截器,首先需要编写一个实现了 `HandlerInterceptor` 的 Java 类: ```java import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 检查用户是否已登录 String user = (String)request.getSession().getAttribute("user"); if(user != null){ return true; // 用户已登录,则放行请求 }else{ // 如果未登录则重定向到登录页面 response.sendRedirect("/login.html"); return false; } } } ``` 上述代码展示了如何在一个名为 `LoginInterceptor` 的类中实现基本的身份验证逻辑[^1]. #### 注册拦截器 为了让应用程序知道要应用哪个拦截器以及何时应该激活它,还需要注册这些组件。这通常是在配置文件中完成的。下面是一个例子展示如何将前面提到的 `LoginInterceptor` 添加到全局配置当中: ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Bean public LoginInterceptor loginInterceptor(){ return new LoginInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()) .addPathPatterns("/**") // 拦截所有路径下的请求 .excludePathPatterns("/favicon.ico", "/user/login"); // 放行特定URL模式 } } ``` 这段配置指定了哪些 URL 路径会被拦截,并排除了一些不需要经过身份验证就能访问的地址[^4]. #### 处理 Body 数据读取问题 对于某些场景下可能遇到的问题——比如尝试在同一请求周期内多次读取消息体而导致错误的情况(如 "Required request body is missing OR Stream closed"),可以通过缓存输入流的方式来解决这个问题。具体做法是利用自定义过滤器提前复制原始 HTTP 请求的内容至缓冲区,然后再将其传递给下游处理器[^2]: ```java @Component public class RequestBodyCacheFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request); filterChain.doFilter(wrappedRequest,response); } } ``` 这样做的好处是可以让多个组件安全地共享同一个请求的消息主体而不会引发冲突。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值