拦截器(interceptor)

一、什么是拦截器?

1.概念

Spring MVC中的拦截器(Interceptor)类似于ServLet中的过滤器(Filter),它主要用于拦截用户请求并作出相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
定义:拦截器是一种动态拦截方法调用的机制,在SpringMVC中动态拦截controller方法的执行;

tomcat所有请求资源中分为静态资源和动态资源,动态资源。
在web容器中,有着监听器、过滤器、servlet几种配置,Tomcat启动时加载配置有着先后顺序。顺序: context-param -> listener -> filter -> servlet/,而SpringMVC框架中在web.xml中配置dispatcherServlet为一个Servlet。所以根据发送的请求 例:(/books) 访问动态资源时先经过过滤器No.1\过滤器No.2等等,然后由SpringMvc的中央处理(DispatcherServlet)将请求交给对应的处理器(Controller)进行处理。因此,拦截器诞生,它的作用就是拦截controller的请求在其前后执行一些操作。
在这里插入图片描述

2.拦截器的作用

(1)拦截器通常在指定的方法调用前后执行一些操作
(2)在某些条件下阻止原始方法的执行,通常用于权限校验,确保只有具备相应权限的用户才能访问特定的方法或资源。
(3)拦截器允许在不修改原有代码的情况下,通过在方法调用前后插入额外的代码来实现功能的增强。

3.拦截器和过滤器的相同点和不同点

(1)相同点:

体现AOP思想:它们都采用了面向切面编程的思想,可以对方法进行增强,实现例如日志记录、登录鉴权等功能。
设定执行顺序:拦截器和过滤器都可以通过Order注解来设定它们处理请求的先后顺序。

(2)不同点:

实现原理:过滤器是依赖于Servlet容器的,它是通过实现Filter接口并注册到web.xml中或使用@WebFilter注解来配置的。而拦截器则是Spring框架的一部分,它通过实现HandlerInterceptor接口并且通常通过Spring的配置来管理。
作用范围:过滤器可以拦截所有请求,包括静态资源和非静态资源的请求。而拦截器只能拦截到controller的请求。
方法不同:过滤器有init(), doFilter(), destroy()三个方法,其中doFilter()对于每次请求都会被调用。拦截器则有preHandle(), postHandle(), afterCompletion()方法,它们分别在请求处理的不同阶段被调用。

二、拦截器的使用

1.导入maven所需要的依赖及根目录下创建所需要的包和类

在这里插入图片描述

 <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
  </dependencies>

2.配置ServletContainersInitConfig类


public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

getServletFilters这个过滤器用于设置请求和响应的字符编码为UTF-8,解决中文乱码的问题

3.配置SpringMvcConfig类

@Configuration
@ComponentScan({"com.example.demo2.controller","com.example.demo2.config"})
@EnableWebMvc
public class SpringMvcConfig {
}

4.定义controller.interceptor目录下的ProjectInterceptor类

在controller目录下创建拦截器的类方便ComponentScan扫描拦截器的bean,简化操作。

@Component

public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

因为在HandlerInterceptor接口中三个方法都是default类型,所以就不需要在所有的实现类中全部重写default方法,哪个实现类需要新增该方法,就在哪个实现类中进行实现。
idea中ctrl+o选择三个方法进行重写。

在这里插入图片描述

5.配置SpringMvcSupport类

这个类中 addResourceHandler方法作用是Spring MVC 框架将请求映射到相应的静态资源,方便访问静态资源。
addInterceptors方法主要作用是注册拦截器,对请求的动态资源进行拦截。

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books");
    }
}

ctrl+o选中addInterceptors方法,拦截请求的路径/books

在这里插入图片描述

6.创建BookoController类

@RestController
@RequestMapping("/books")

public class BookController {
    @GetMapping
    public String getAll() {
        System.out.println("book getAll");
        return "{'module':'book getAll'}";
    }

7.创建Book类

Book类中属性分别为id、type 、name、description,get和set方法省略了

  private Integer id;
    private String type;
    private String name;
    private String description;

8.测试

运行Tomcat后在postman中发送Get请求回到控制台查看效果
在这里插入图片描述
总结:preHandle: 在请求处理之前执行。在这个例子中,先打印了"Prehandle",表示在处理请求之前执行了拦截器的预处理逻辑。

book getAll: 这是controller方法的调用,用于获取所有的书籍信息。

postHandle: 在请求处理之后,视图渲染之前执行。在这个例子中,它打印了"Posthandle",表示在处理请求并准备渲染视图之前执行了拦截器的后处理方法。

afterCompletion: 在整个请求结束之后执行。

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值