SpringBoot拦截器Interceptor

在开发短信注册功能时,希望用户在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");
    }
}