Spring Boot中使用过滤器

简介: 对于前后端分离的项目来说跨域是一个难题,对于跨域问题有多中解决方案,比如JSONP,网关支持等等。主要介绍如何使用过滤器来解决跨域问题。

1、什么是过滤器

Filter 也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务 器管理的所有web资源:例如JSP,Servlet,静态图片文件或静态HTML文件进行拦截,从而实现一些 特殊功能。例如实现 URL级别的权限控制 、 过滤敏感词汇 、 压缩响应信息 等一些高级功能。

2、Filter的执行原理

当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户 请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过 过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根 据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理 后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务
image.png

服务器会按照过滤器定义的先后循序组装成 一条链,然后一次执行其中的doFilter()方法。(注:这一点 Filter 和 Servlet是不一样的)执行的顺序就如下图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter() 之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。
image.png

3、如何自定义一个Filter

只需要实 现 javax.servlet.Filter 这个接口,重写其中的方法。实例如下:

import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

@Component
public class CrosFilter implements Filter {
   
   
    //重写其中的doFilter方法
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws
            IOException, ServletException {
   
   
        //继续执行下一个过滤器
        chain.doFilter(req, res);
    }
}

4、Spring Boot如何配置Filter

自定义好了过滤器当然要使其在Spring Boot中生效了,Spring Boot配置Filter有两种方式,其实都很 简单,下面一一介绍。

1、配置类中使用@Bean注入【推荐使用】

其实很简单,只需要将 FilterRegistrationBean 这个实例注入到IOC容器中即可,如下:

@Configuration
public class FilterConfig {
   
   

    @Autowired
    private Filter1 filter1;
    @Autowired
    private Filter2 filter2;

    /**
     * 注入Filter1 * @return
     */
    @Bean
    public FilterRegistrationBean filter1() {
   
   
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(filter1);
        registration.addUrlPatterns("/*");
        registration.setName("filter1");
        //设置优先级别
        registration.setOrder(1);
        return registration;
    }

    /**
     * 注入Filter2 * @return
     */
    @Bean
    public FilterRegistrationBean filter2() {
   
   
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(filter2);
        registration.addUrlPatterns("/*");
        registration.setName("filter2");
        //设置优先级别
        registration.setOrder(2);
        return registration;
    }
}

注意:设置的优先级别决定了过滤器的执行顺序。

2、使用@WebFilter

@WebFilter 是Servlet3.0的一个注解,用于标注一个Filter,Spring Boot也是支持这种方式,只需要在 自定义的Filter上标注该注解即可,如下:

@WebFilter(filterName = "crosFilter", urlPatterns = {
   
   "/*"})
public class CrosFilter implements Filter {
   
   
    //重写其中的doFilter方法
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws
            IOException, ServletException {
   
   
        //继续执行下一个过滤器
        chain.doFilter(req, response);
    }
}

要想 @WebFilter 注解生效,需要在配置类上标注另外一个注解@ServletComponentScan用于扫描使其生效 ,如下:

@SpringBootApplication
@ServletComponentScan(value = {
   
   "com.xxx.filter"})
public class SpringbootApplication {
   
   }

3、示例

对于前后端分离的项目来说跨域是一个难题,对于跨域问题有多中解决方案,比如JSONP,网关支持等等。主要介绍如何使用过滤器来解决跨域问题。

其实原理很简单,只需要在请求头中添加相应支持跨域的内容即可,如下代码仅仅是简单的演示下,针对细致的内容还需自己完善,比如白名单等等。

package com.jrm.filter;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CrosFilter implements Filter {
   
   
    //重写其中的doFilter方法
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws
            IOException, ServletException {
   
   

        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", " Origin, X-Requested-With, Content-Type,Accept");
        //继续执行下一个过滤器
        chain.doFilter(req, response);

    }
}

配置类中注入FilterRegistrationBean,如下代码:

package com.jrm.config;

import com.jrm.filter.CrosFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

@Configuration
public class FilterConfig {
   
   
    @Autowired
    private CrosFilter crosFilter;

    /**
     * 注入crosFilter * @return
     */
    @Bean
    public FilterRegistrationBean crosFilter() {
   
   
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(crosFilter);
        registration.addUrlPatterns("/*");
        registration.setName("crosFilter");
        //设置优先级别
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}
目录
相关文章
|
2月前
|
Java 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
182 4
如何在SpringBoot项目中使用过滤器和拦截器
|
3月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
229 0
|
1月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
24 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
2月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
52 3
|
3月前
|
安全 搜索推荐 Java
|
3月前
|
前端开发 Java 开发者
|
3月前
|
安全 Java 开发者
|
3月前
|
安全 Java 测试技术
Spring Security 中的委托过滤器代理
【8月更文挑战第21天】
38 0
|
5月前
|
Java 开发者 Spring
Spring项目中Ordered接口的应用:全局过滤器(GlobalFilter)的顺序控制
Spring项目中Ordered接口的应用:全局过滤器(GlobalFilter)的顺序控制
230 2
|
5月前
|
Java API 数据安全/隐私保护
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
84 6