springboot二:过滤器、拦截器、静态资源访问

本文介绍了SpringBoot中过滤器和拦截器的使用,包括它们的概念、作用、代码实现及应用场景。过滤器主要用于在请求处理前进行拦截,如检查登录状态;拦截器则在请求处理前后进行干预,实现AOP功能。同时,文章还讲解了SpringBoot如何配置静态资源路径,允许访问静态文件。

一:springboot中的过滤器

过滤器是什么?

它是基于Servlet 技术实现的, 简单的来说,过滤器就是起到过滤的作用,在web项目开发中帮我们过滤一些指定的 url做一些特殊的 处理。

过滤器主要做什么?

过滤掉一些不需要的东西,例如一些错误的请求。

也可以修改请求和相应的内容。

也可以拿来过滤未登录用户

过滤器的代码实现?

过滤器(filter)有三个方法,其中初始化(init)和摧毁(destroy)方法一般不会用到,主要用到的是doFilter这个方法。

怎么过滤呢?

如果过滤通过,则在doFilter执行 filterChain.doFilter(request,response); 。

实现的方式?

自定义Filter有两种实现方式,第一种是使用@WebFilter,第二种是使用 FilterRegistrationBean。

1.1 @WebFilter 实现

属性名                          类型                   描述

filterName                   String                 指定该Filter的名称

urlPatterns                  String                 指定该Filter所拦截的URL。

value                           String                 与 urlPatterns 一致

1. 创建一个MyFilter.java实现Filter接口

@WebFilter(urlPatterns = "/api/*",filterName = "myFilter")
@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
public class MyFilter implements Filter {
  @Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("初始化过滤器");
}
@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        String uri=request.getRequestURI();
        String method=request.getMethod();
        System.out.println(uri+" "+method+"哈哈我进入了 MyFilter 过滤器了");
        filterChain.doFilter(servletRequest,servletResponse);
    
   }
}

2. 启动类加上 @ServletComponentScan 注解

3. 创建一个 FilterController 接口

@RestController
@RequestMapping("/api")
public class HelloController {
    @GetMapping("/user/filter")
    public String hello(){
        return "哈哈我通过了过滤器";
   }
}

4.测试

1.2 FilterRegistrationBean 实现

1. 创建 FilterConfig

@Configuration
public class FilterConfig {
   @Bean
    public MyFilter myFilter(){
        return new MyFilter();
   }
    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(MyFilter myFilter){
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
        /**
         * 设置过滤器
         */
        filterRegistrationBean.setFilter(MyFilter());
        /**
         * 拦截路径
         */
        filterRegistrationBean.addUrlPatterns("/api/*");
        /**
         * 设置名称
         */
        filterRegistrationBean.setName("myFilter");
        /**
         * 设置访问优先级 值越小越高
         */
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
   }
}

2. 修改 MyFilter.java

//@WebFilter(urlPatterns ={"/api/*"},filterName = "myFilter")

3. 修改启动类

//@ServletComponentScan

4. 测试

2. 过滤校验用户是否登录demo

1. 修改 application.properties 加入开发接口通配地址

#凡是请求地址层级带有 open 都放行
open.url=/**/open/**

2. 修改 MyFilter

//@WebFilter(urlPatterns ={"/*"},filterName = "myFilter")
public class MyFilter implements Filter {
    @Value("${open.url}")
    private String openUrl;
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("初始化 myFilter 过滤器");
   }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestUrl = request.getRequestURI();
        System.out.println("过滤器MyFilter拦截了请求为" + requestUrl);
        //首先校验是否是开放 api
        //是直接放行,否再校验token
        PathMatcher matcher = new AntPathMatcher();
        if(matcher.match(openUrl,requestUrl)){
            filterChain.doFilter(servletRequest,servletResponse);
       }else {
            String token=request.getHeader("token");
            if(StringUtils.isEmpty(token)){
                servletRequest.getRequestDispatcher("/api/open/unLogin").forward(servletRequest,
                        servletResponse);
           }else {
                filterChain.doFilter(servletRequest,servletResponse);
           }
       }
   }
}

3. 新增 未登录接口、首页接口

@GetMapping("/open/home/info")
    public Map<String,String> getHome(){
        Map<String,String> map=new HashMap<>();
        map.put("游客","欢迎访问首页");
        return map;
   }
    
    @GetMapping("/open/unLogin")
    public String getUnauthorized(){
        return "登录失效,请重新登录";
   }

 

通过直接访问开放接口和访问需权鉴接口进行测试

二、springboot中的拦截器

2.1拦截器

拦截器是什么?

 简单的来说,就是一道阀门,在某个方法被访问之前,进行拦截,然后在之前或之后加入某些操作,拦截器是AOP 的一种实现策略。

拦截器主要做什么?

对正在运行的流程进行干预。

拦截器的代码实现。

拦截器也主要有三个方法:

其中preHandle是在请求之前就进行调用,如果该请求需要被拦截,则返回false,否则true;

postHandle是在请求之后进行调用,无返回值;

afterCompletion是在请求结束的时候进行调用,无返回值

2.2 在 springBoot 中使用拦截器

步骤:创建一个类实现 HandlerInterceptor 接口,再创建一个配置类实现 WebMvcConfigurer接口 ,重写 addInterceptors 方法。

1. 创建我们自己的拦截器类并实现 HandlerInterceptor 接口。

public class MyInterceptor implements HandlerInterceptor {
    @Value("${open.url}")
    private String openUrl;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object
handler) throws Exception {
        System.out.println("MyInterceptor....在请求处理之前进行调用(Controller方法调用之前)");
        String requestUrl=request.getRequestURI();
        System.out.println("过滤器MyFilter拦截了请求为"+requestUrl);
        return true;
   }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object
handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor...请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之
后)");
   }
  
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object
handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor....在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对
应的视图之后执行(主要是用于进行资源清理工作)");
   }
}

 

2.修改 application.properties 加入开发接口通配地址.

#开放性接口
open.url=/**/open/**

 

3.创建一个 Java 实现 WebMvcConfigurer , 并重写 addInterceptors 方法

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Value("${open.url}")
    private String openUrl;
    @Bean
    public MyInterceptor getMyInterceptor(){
        return new MyInterceptor();
   }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
      
registry.addInterceptor(getMyInterceptor()).addPathPatterns("/api/**").excludePathPatterns(openUrl
);
   }
}

 

4. 创建开放首页接口

@RestController
@RequestMapping("/api")
public class InterceptorController {
       @GetMapping("/home/open/info")
    public String home(){
        return "欢迎来到首页";
   }
    @GetMapping("/user/interceptor")
    public String interceptor(){
        return "我被拦截了并通过了拦截器";
   }
}

5. 测试

带有open http://localhost:8080/api/open/home/info 不拦截

其他没通过公开接口访问的都会被拦截

三、springboot静态资源的访问

1.源码分析

1. 我们打开 ResourceProperties 资源配置类

默认的静态资源路径为:

classpath:/META-INF/resources/

classpath:/resources/

classpath:/static/

classpath:/public

只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。 我们习惯会把静态资源放在classpath:/static/ 目 录下。

2.测试

1. 把 test.png 图片放入 static 文件夹

2.访问

 

 

 

### Spring Boot过滤器拦截器的使用场景及区别 #### 1. 基本概念 - **过滤器(Filter)** 是 Java Servlet 规范的一部分,由 Servlet 容器管理。它可以在请求到达 DispatcherServlet 或响应返回客户端前执行操作[^3]。 - **拦截器(Interceptor)** 则是由 Spring 提供的一种 AOP 实现方式,主要用于 Controller 层之前的预处理和后处理[^1]。 --- #### 2. 主要区别 | 特性 | 过滤器(Filter) | 拦截器(Interceptor) | |-------------------------|--------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| | **生命周期管理** | 由 Servlet 容器管理 | 由 Spring 容器管理 | | **触发时机** | 请求进入容器到 servlet 处理之前;servlet 返回数据之后 | 控制器方法调用前后 | | **依赖关系** | 不依赖 Spring 容器 | 可以访问 Spring 的 IOC 容器,支持 DI 和 AOP | | **适用范围** | 所有请求都可以被拦截,包括静态资源 | 默认不拦截静态资源,需手动配置放行 | | **功能扩展** | 功能较为简单,适合通用需求 | 更灵活,可实现复杂业务逻辑 | --- #### 3. 配置与使用 ##### (1)过滤器的配置与使用 通过 `@Bean` 注解定义一个 Filter 并注册到应用上下文中: ```java @Configuration public class MyFilterConfig { @Bean public FilterRegistrationBean<TsanFilter> tsanFilter() { FilterRegistrationBean<TsanFilter> registrationBean = new FilterRegistrationBean<>(); TsanFilter filter = new TsanFilter(); registrationBean.setFilter(filter); registrationBean.addUrlPattern("/*"); return registrationBean; } } ``` 其中,`TsanFilter` 类实现了 `javax.servlet.Filter` 接口,并重写了其核心方法 `doFilter()`[^5]。 --- ##### (2)拦截器的配置与使用 自定义拦截器类需要继承 `HandlerInterceptorAdapter` 或实现 `HandlerInterceptor` 接口: ```java @Component public class PageInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Pre Handle method is Calling"); return true; // 继续后续流程 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Post Handle method is Calling"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Request and Response are completed"); } } ``` 接着在全局配置文件中注册该拦截器: ```java @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new PageInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/page/login", "/user/login", "/static/**"); // 放行特定路径 } ``` 注意:Spring Boot 2.x 后默认会拦截静态资源,因此需要显式排除这些路径[^4]。 --- #### 4. 使用场景分析 - **过滤器** - 对所有 HTTP 请求进行统一处理,比如日志记录、权限校验、编码转换等[^2][^3]。 - 当项目未基于 Spring 开发时,仅能依靠过滤器完成类似功能[^2]。 - **拦截器** - 聚焦于控制器层的操作,例如参数验证、用户登录状态检查以及性能监控等[^1]。 - 若涉及复杂的业务逻辑或者需要利用 Spring 上下文中的 Bean,则优先
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值