在开发短信注册功能时,希望用户在60s内只能获取一次验证码。因此使用SpringBoot中的拦截器。Interceptor和Filter一样,都是AOP的具体实现。
自定义拦截器
在新闻自媒体项目中,我使用Redis来存取短信验证码,因此需要自定拦截器,在用户访问到达controller层前,检测Redis,如果60s内该ip没有进行访问,则放行。
如果拦截器须实现 org.springframework.web.servlet.HandlerInterceptor
接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter
类,并且需要重写下面下面 3 个方法:
- preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)
- postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
- afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)
public class PassportInterceptor implements HandlerInterceptor {
@Autowired
public RedisOperator redis;
public static final String MOBILE_SMSCODE = "mobile:smscode";
/**
* 在进入controller之前拦截请求
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获得用户ip
String userIp = IPUtil.getRequestIp(request);
boolean keyIsExit = redis.keyIsExist(MOBILE_SMSCODE + ":" + userIp);
if(keyIsExit){
System.out.println("频率过快");
return false;
}
/**
* return false:请求被拦截
* return true:请求放行
*/
return true;
}
/**
* 在请求访问到controller后,渲染视图之前
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* controller之后,渲染视图之后
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
配置拦截器
在自定义拦截器后,需要将其在MVC容器中注册;在加入拦截器的同时,还需传入路由地址。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public PassportInterceptor passportInterceptor(){
return new PassportInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(passportInterceptor())
.addPathPatterns("/passport/getSMSCode");
}
}