Spring MVC 拦截器(Interceptor)用法详解
什么是拦截器
拦截器是Spring MVC框架中的一种增强处理器,拦截器也可以称为过滤器(Filter)或者AOP实现,它可以在请求处理的过程中预处理请求、处理请求和处理完请求后进行后续处理。拦截器可以将特定的处理逻辑应用到整个应用程序或者某个特定的Controller中。
和Servlet的过滤器(Filter)相比较,拦截器可以获取Spring IoC容器中的Bean,并利用依赖注入和AOP技术对目标代码进行更具体的处理,因此拦截器的应用范围远比过滤器广泛。
使用拦截器的原因
拦截器本质上就是对目标请求进行预处理和后处理,它可以使得我们在请求处理的前后执行我们自己的代码,比如对请求进行安全性检查、记录日志等操作,而无需进入具体的业务处理逻辑中。拦截器对于那些不需要更复杂的过滤器逻辑,但又需要在某些场景中进行拦截和处理的场景非常适用。
拦截器的配置方法
事实上,在Spring MVC中使用拦截器非常简单,只需要完成以下三个步骤。
步骤一:拦截器的实现
实现自己的拦截器类,实现HandlerInterceptor
接口,并实现以下三个方法:
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
三个接口方法的作用详解:
-
preHandle
: 在请求之前进行调用,也就是在Controller方法调用之前。 -
postHandle
: 在请求之后调用,也就是在Controller方法调用之后,但是渲染视图之前。 -
afterCompletion
: 在整个请求处理完成后进行调用,也就是在视图渲染完毕或者调用方取消时(比如当请求出现异常)。
步骤二:拦截器的注册
拦截器的注册过程非常类似于Spring IoC容器对Bean的注册,只不过是使用了一种专门的注解@Configuration
,然后将拦截器的实例化对象添加到spring的上下文之中。
以下是部分示例代码,并未涉及全部内容,请结合实际代码食用
示例一:对请求进行日志记录
目的:记录每个请求的url、请求参数、响应时间。
首先,我们需要编写一个拦截器类,键入以下代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogInterceptor implements HandlerInterceptor {
private static Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("Request [{}] URL: {}", request.getMethod(), request.getRequestURL().toString());
logger.info("Request params: {}", request.getParameterMap().toString());
request.setAttribute("startTime", System.currentTimeMillis()); //记录开始时间
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
long startTime = (long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
logger.info("Response time: {}ms", endTime - startTime);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// Do nothing here.
}
}
我们通过实现HandlerInterceptor
接口来实现自己的拦截器,这个拦截器简单地将请求的URL和参数记录到log中,并在请求结束时计算响应时间。
接下来,我们需要在Spring MVC中注册这个拦截器。打开Spring配置文件,新增如下配置:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.yourpackage.LogInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
这段配置包含了一个拦截器LogInterceptor
和路径/**
,意味着我们将会监控所有的请求并且记录下日志。
示例二:请求防重复提交
至于本例子的目的,由于网上很多存在前后端分离实现的方式,所以这里只针对后端表单提交进行课程。
- 以提交的url为唯一性校验点,对重复提交进行防范。
在前端给提交按钮添加一个token
字段,后端对于这个token
进行判定,防止多次提交。
首先,我们需要在拦截器中保存已处理过的请求URL,实现如下:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.Set;
public class TokenInterceptor implements HandlerInterceptor {
private static final Set<String> URL_SET = new HashSet<>(); //保存请求URL
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final String url = request.getRequestURL().toString();
synchronized (URL_SET) {
if (URL_SET.contains(url)) {
return false;
}
URL_SET.add(url);
}
request.setAttribute("token", url);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
final String url = request.getAttribute("token").toString();
synchronized (URL_SET) {
URL_SET.remove(url);
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
}
接下来,我们需要在Spring MVC中注册这个拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/form" />
<bean class="com.yourpackage.TokenInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
这段配置设置了拦截路径/form
,意味只有带有该路径的请求才会进行防重复提交的拦截处理。
总结
本文介绍了Spring MVC中拦截器的使用方法,为开发者实现增强的请求处理提供了一种便利、高效的方式。值得注意的是,拦截器需要遵循Spring MVC部分原则,比如需要放在Contexts中,并且需要先于业务逻辑被执行。在设计拦截器的过程中,经验和设计能力至关重要。
文章仅作参考,请结合实际开发进行食用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring MVC 拦截器 interceptor 用法详解 - Python技术站