SpringBoot中HandlerInterceptorAdapter使用

简介:
在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。

应用场景

日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。 权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
性能监控:典型的是慢日志。

在HandlerInterceptorAdapter中主要提供了以下的方法:
preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
postHandle:在方法执行后调用。
afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。

实现
1.自定义一个类继承HandlerInterceptorAdapter


@Service
public class AccessInterceptor extends HandlerInterceptorAdapter {
	//用map来代替redis测试
    private static Map<String,Integer> map=new ConcurrentHashMap<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //自定义拦截器

        if(handler instanceof HandlerMethod){


            String name=request.getParameter("name");
           

            HandlerMethod hm = (HandlerMethod)handler;
           //搭配自定义注解使用
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if(accessLimit == null) {
                return true;
            }
            int seconds = accessLimit.maxCount();
            if(map.getOrDefault(name,0)>seconds){//超过最大次数 不给通过
                return false;
            }else{
                map.put(name,map.getOrDefault(name,0)+1);
            }

        }

        return true;
    }
}

2.注册到WebMvcConfigurerAdapter中

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    AccessInterceptor accessInterceptor;

    /**
     * 注册accessInterceptor才能正常使用
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(accessInterceptor);
    }
}

两步即可完成拦截实现。

另外可以在自定义拦截里面搭配注解使用。比如实现短时间限定用户访问次数。可考虑搭配redis使用

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {

    int maxCount();//一定时间内的访问次数
    boolean needLogin() default true;
}

controller层使用,在需要拦截的方法上面加注解并设置最大值

  	@AccessLimit(maxCount = 5)//最大设置为5
    @GetMapping("/access/{name}/{age}")
    @ResponseBody
    public String TestAccessLimit(HttpServletRequest request,@RequestParam("name") String name){
       //doSomething
    }

版权声明:本文为ocean35原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。