天天看点

Spring拦截器的实现以及通过注解实现拦截

本篇是本人记录对于Spring的拦截器简单的使用记录,以及通过自定义注解的方式实现其拦截目的

首先看一下简单的实现

第一步:定义一个测试类,用于向后台发送请求

@RestController
public class Hello {

    @RequestMapping("/sayHello")
    public String sayHello(){
        return "Hello,World!";
    }
    
    @RequestMapping("/helloInterceptor")
    public String helloInterceptor(){
        return "访问helloInterceptor";
    }

}
           

第二步:定义一个自己的拦截器,需要实现Spring提供的HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
    	Object handler) throws Exception {
    		response.setContentType("application/json; charset=utf-8");
            String a = request.getParameter("a");
            if(null != a && a.equals("a"){
                return true;
            }else {
                response.getWriter().print("你访问的资源需要登录");
                return false;
            }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
    	Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
    	Object handler, Exception ex) throws Exception {

    }
}
           

这一步中,我们要求所有请求都需要带上指定的参数a,参数的值也是a,如果向后台发送到请求没有加上这个参数值的话,那么就会被拦截,反之则不会;

第三步:将上面的拦截器添加到拦截器链中,这里需要定义一个实现了WebMvcConfigurer接口的配置类

@Configuration
public class MyInterceptorConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//这种方式会拦截所有请求
    	//registry.addInterceptor(new MyInterceptor());
    	//这种方式会拦截指定的请求
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/helloInterceptor");
    }
}
           

好了,以上三部完成后,一个简单的web请求拦截器就已经可以使用了

接下来,启动项目,并在浏览器中进行访问

第一次请求

:sayHello

Spring拦截器的实现以及通过注解实现拦截

OK我们看到,这次请求未被拦截,顺利执行了

这是因为我们在拦截器链中指定了只对**helloInterceptor()**的访问进行拦截

第二次请求

:helloInterceptor

Spring拦截器的实现以及通过注解实现拦截

OK我们看到,这次的请求被拦截了,因为我们没有按要求带上指定的参数

第三次请求:

helloInterceptor?a=a

Spring拦截器的实现以及通过注解实现拦截

好的我们可以看到,当我们按照要求带上指定的参数后,那么请求是可以正确到达我们的目标方法的

通过上面的测试,可以看到,上面的方法虽然可以对访问请求进行拦截,但是当我们项目中的接口很多的时候,往往需要我们对大量的访问请求的进行拦截指定

那么接下来,再来看一下,如何通过注解,来实现对访问请求的拦截

首先,我们定义一个自定义的注解

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

}

           

自定义注解的各个参数这里就不进行过多的描述了,这并不是本篇的重点;

自定义注解定义好了之后,我们首先想修改一下我们的测试类

@RestController
public class Hello {

    @RequestMapping("/sayHello")
    public String sayHello(){
        return "Hello,World!";
    }

    @LoginIntercept
    @RequestMapping("/helloInterceptor")
    public String helloInterceptor(){
        return "访问helloInterceptor";
    }

}
           

注意,我们在 /helloInterceptor方法的上面,加上了我们自定义的注解,而**/sayHello**方法上面并没有加

然后对原先的拦截器方法进行修改

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
    	Object handler) throws Exception {
    	//获取方法处理器
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        LoginIntercept loginIntercept = 
        	handlerMethod.getMethod()//这一步是获取到我们要访问的方法
        	//然后根据我们制定的自定义注解的Class对象来获取到对应的注解
        	.getAnnotation(LoginIntercept.class);
        	
        //如果要访问的方法上没有加这个注解,那么就说明这个方法不需要拦截,否则就需要进行拦截
        if(null == loginIntercept){
            System.out.println("访问的方法无需拦截");
            return true;
        }else {
        response.setContentType("application/json; charset=utf-8");
        String a = request.getParameter("a");
        if(null != a && a.equals("a")){
                return true;
            }else {
                response.getWriter().print("请求被拦截");
                return false;
            }
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
    	Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
    	Object handler, Exception ex) throws Exception {

    }
}
           

最后修改一下我们的配置类

@Configuration
public class MyInterceptorConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
}
           

现在,我们的配置类将会对所有方法进行拦截,接下来我们看一下不同的访问结果

Spring拦截器的实现以及通过注解实现拦截
Spring拦截器的实现以及通过注解实现拦截
Spring拦截器的实现以及通过注解实现拦截

很显然,访问的结果和之前的三次访问结果一模一样,但是不同的是,当我们现在访问sayHello是,控制台输出了一句话:访问的方法无需拦截

以上就是本人对于Spring拦截器的简单实现以及通过自定义注解实现访问拦截的test记录,其中的核心分别是Spring的

HandlerInterceptor接口

及其 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 方法

和Spring的

WebMvcConfigurer接口

及其 public void addInterceptors(InterceptorRegistry registry) 方法

继续阅读