针对“Springboot项目快速实现拦截器功能”,我可以提供以下完整攻略:
1. 引入依赖
在pom.xml中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.3</version>
</dependency>
2. 编写拦截器
在springBoot中,实现自定义拦截器需要实现HandlerInterceptor
接口,该接口包含三个方法:
preHandle()
:在请求处理之前进行调用(Controller方法调用之前)。postHandle()
:请求处理之后进行调用,但是在视图被渲染之前,即在返回ModelAndView之前调用(Controller方法调用之后)。afterCompletion()
:在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于清理资源等工作)。
下面给出一个简单的示例代码,可以实现对请求的耗时进行统计的功能:
public class TimeInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(TimeInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
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");
logger.info("请求耗时:{} ms", System.currentTimeMillis() - startTime);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// do nothing
}
}
3. 注册拦截器
在springBoot中,需要通过WebMvcConfigurer
来注册拦截器,示例代码如下:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TimeInterceptor()).addPathPatterns("/**");
}
}
其中,addPathPatterns("/**")
表示需要拦截所有请求。
示例1
在上面的示例中,我们只是简单地打印了请求的耗时。现在我们来看一个更加实际一些的例子。
需求:拦截需要登录的接口,只有在登录状态下才能访问。
首先,我们需要在HttpServletRequest
中获取session中的信息判断是否登录,示例代码如下:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object user = session.getAttribute("userInfo");
if (user == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
在上面代码中,我们判断了session中是否存在userInfo
信息,如果不存在,则跳转到登录页面。如果存在,则直接返回true,表示继续执行下面的接口方法。
示例2
除了判断登录状态外,我们还可以在拦截器中进行一些其他的业务逻辑,在这里我们思考一个接口访问频率限制的问题。
需求:拦截某个接口,如果一段时间内(比如1秒钟)请求的次数超过一定的阈值(比如10次),则拒绝该请求。
通过使用redis记录该接口的访问次数,并配合定时任务刷新次数,可以实现该功能。具体实现代码如下:
public class RequestLimitInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(RequestLimitInterceptor.class);
private RedisTemplate<String, Integer> redisTemplate;
@Autowired
public void setRedisTemplate(RedisTemplate<String, Integer> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestUri = request.getRequestURI();
String redisKey = "req_limit:" + requestUri;
// 访问次数加1
Integer count = redisTemplate.opsForValue().get(redisKey);
if (count == null) {
redisTemplate.opsForValue().set(redisKey, 1, 1, TimeUnit.SECONDS);
} else {
if (count > 10) {
response.getWriter().write("请求过于频繁");
logger.warn("请求过于频繁,URI={}", requestUri);
return false;
} else {
redisTemplate.opsForValue().increment(redisKey, 1);
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// do nothing
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// do nothing
}
}
其中,我们使用了redis来记录该接口的访问次数,并设置了1秒钟的过期时间。当访问次数超过10次时,直接返回错误信息。
总结
上述就是实现自定义拦截器的完整攻略,包括引入依赖、编写拦截器、注册拦截器以及两个示例。需要注意的是,在实际项目中,我们还需要考虑一些其他的问题,比如拦截器的执行顺序、多个拦截器的综合作用等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot项目快速实现拦截器功能 - Python技术站