SpringBoot 实现拦截器

拦截器在实际工作中使用比较广泛且相当重要,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,等等。在SpringMVC中,我们可以通过XML配置文件来配置一个拦截器,操作起来也很简单。在SpringBoot中我们需要通过代码的形式来配置一个拦截器,同样操作起来也十分简单,下面我们一起来看一下吧。

项目结构

这里写图片描述

这是一个实现拦截器的小测试项目,包括以下几个文件:

  1. CustemConfigurerAdapter : 用来配置具体拦截器实现类与访问路径关系的配置注册类
  2. HelloController : 测试的Controller,我们请求这个Controller来验证拦截器是否生效
  3. RequestInterceptor : 拦截器具体实现类
  4. Application : 服务启动类
  5. application.properties : SpringBoot服务中的配置文件,服务启动时会读取这个文件中的配置项
  6. pom.xml : 所需要的Jar POM配置

下面我们将详细讲解上述中的几个文件,来实现一个拦截器。

代码详解

CustemConfigurerAdapter

/**
 * 自定义配置项类,该类中和存入拦截器、过滤器等配置项信息
 * @author Administrator
 */
@Configuration
public class CustemConfigurerAdapter extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 将请求拦截器与Path请求路径对应起来并进行注册
        registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/*");
    }
}

这个类中会保存一系列的自定义配置项信息,不仅可以保存拦截器配置,其他的配置项也可以写在该类中。

HelloController

@RestController
public class HelloController {

    @RequestMapping("/test")
    @ResponseBody
    public String test() {
        System.out.println("当前Controller处理中...");
        return "hello world";
    }

}

该方法是一个极其简单的请求方法,请求Path为:/test,返回信息为hello world。

RequestInterceptor

/**
 * 请求拦截器
 * @author Administrator
 *
 */
public class RequestInterceptor implements HandlerInterceptor {

    /**
     * 该方法需要当前对应的Interceptor 的preHandle方法的返回值为true 时才会执行。
     * 顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。
     * 这个方法的主要作用是用于进行资源清理工作的
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object object, Exception exception) throws Exception {

    }

    /**
     * 处理器处理之前调用
     */
    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object object) throws Exception {
        System.out.println("在Controllrt处理之前执行...");
        return true;
    }

    /**
     * 处理器处理之后调用
     */
    @Override
    public void postHandle(HttpServletRequest request, 
            HttpServletResponse response, Object object, ModelAndView mv) throws Exception {
        System.out.println("在Controllrt处理之后执行...");
    }

}

该类为具体的拦截器实现类,拦截器实现类需要实现HandlerInterceptor接口,并根据需要对其中的三个方法进行实现。这三个方法分别为:afterCompletionpreHandlepostHandle

preHandle

该方法将在请求处理之前进行调用。SpringMVC中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

postHandle

由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。

afterCompletion

该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

Application

@SpringBootApplication
@Controller
@ComponentScan(basePackages={"com.test.spring.boot"})   // 自定义自动扫描
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

SpringBoot服务启动类,这是SpringBoot服务启动类的基本配置,可以从任何SpringBoot入门教程中了解。

application.properties

# 服务端口
server.port=8083

SpringBoot服务配置文件,这里仅配置了端口为 8083,其他配置可以根据需要配置。

pom.xml

<build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/>
  </parent>

  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <java.version>1.8</java.version>
  </properties>

  <dependencies>

    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter</artifactId>  
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
  </dependencies>

执行结果

执行 localhost:8083/test,通过控制台log可以知道是否执行了拦截器,并且拦截器方法执行顺序。

这里写图片描述

发布了112 篇原创文章 · 获赞 94 · 访问量 51万+

猜你喜欢

转载自blog.csdn.net/A632189007/article/details/78595763