SpringBoot 过滤器 filter 3种方法

文章目录

  • 前言
  • 一、3种配置Spring Boot过滤器的方法
  • 二、web.xml的配置
  • 三、Spring Boot过滤器方式1,使用@WebFilter注解
    • 1.WebFilter的常用属性
    • 2.使用方法
    • 3.代码演示
  • 四、Spring Boot过滤器方式2,使用FilterRegistrationBean
    • 1.自定义类演示
    • 2.第三方jar演示
  • 五、Spring Boot过滤器方式3,实现ServletContextInitializer接口
    • 1.代码演示
  • 总结


前言

最近Spring Boot项目做单点登录对接的时候,在配置过滤器的时候,找了几种方法,记录一下。欢迎评论补充沟通~
由于之前JAVA Web项目最开始都有web.xml配置,随着框架慢慢的进化,从Spring Boot开始,已经没有了web.xml配置文件。
那原来在web.xml里,配置的filter过滤器,在Spring Boot中怎么配置呢?


一、3种配置Spring Boot过滤器的方法

  1. 实现Filter接口,使用@WebFilter注解

    过滤和实现都有,但是@order排序只能根据过滤器的类名排序

  2. 使用FilterRegistrationBean

    主要是过滤,实现类要单独写,可以自定义排序

  3. 实现ServletContextInitializer接口

    主要是过滤,实现类要单独写,目前没试能不能排序

二、web.xml的配置


  
  <filter>
    <filter-name>SPDispacherfilter-name>
    <filter-class>org.xxx.SpFilterWrapperfilter-class>
  filter>
  
  <filter>
    <filter-name>SessionIntegrationFilterfilter-name>
    <filter-class>org.xxx.AgentSessionIntegrationFilterfilter-class>
  filter>
  
  <filter>
    <filter-name>AuthorizationFilterfilter-name>
    <filter-class>org.xxx.AgentAuthzBaseRoleFilterfilter-class>
  filter>
  
  

  <filter-mapping>
    <filter-name>SPDispacherfilter-name>
    <url-pattern>*.jspurl-pattern>
  filter-mapping>
  <filter-mapping>
    <filter-name>SPDispacherfilter-name>
    <url-pattern>/service/*url-pattern>
  filter-mapping>
  <filter-mapping>
    <filter-name>SPDispacherfilter-name>
    <url-pattern>/SAML2/*url-pattern>
  filter-mapping>
  <filter-mapping>
    <filter-name>SessionIntegrationFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <filter-mapping>
    <filter-name>AuthorizationFilterfilter-name>
    <url-pattern>/service/*url-pattern>
  filter-mapping>
  

三、Spring Boot过滤器方式1,使用@WebFilter注解

这种方式,可以在doFilter()方法中,写具体的过滤逻辑。
@WebFilter注解中写上属性,可以设置过滤的路径等等。
以上web.xml里的filter-class为已经封装好的第三方jar里的类。所以此处代码演示,与以上web.xml无关。

1.WebFilter的常用属性

SpringBoot 过滤器 filter 3种方法_第1张图片

属性名 类型 默认值 作用
filterName String “” 指定过滤器的 name 属性
value String[] {} 该属性等价于 urlPatterns 属性。两者不应该同时使用
urlPatterns String[] {} 指定一组过滤器的 URL 匹配模式
servletNames String[] {} 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中的取值
dispatcherTypes DispatcherType DispatcherType.REQUEST 指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST
initParams WebInitParam[] {} 指定一组过滤器初始化参数
asyncSupported boolean false 声明过滤器是否支持异步操作模式
description String “” 该过滤器的描述信息
displayName String “” 该过滤器的显示名,通常配合工具使用

2.使用方法

  1. 自定义类,实现 implements Filter接口。
  2. 自定义类,添加@WebFilter注解和属性。(这里我试了下,只写@WebFilter注解,不加任何属性,也能过滤全部的路径)
  3. 自定义类,不要加@Component或者@configuration注解。(这里有个坑,如果加了,设置的urlPatterns属性不好用,还是会过滤全部的)
  4. 启动类,添加@ServletComponentScan注解。(配合第3步,SpringBootApplication 上使用@ServletComponentScan 注解后,Filter可以直接通过@WebFilter注解自动注册)

备注:自定义类上,可以设置过滤器的顺序@Order(1),这个网上说不好用,还是根据过滤器类名排序的。

3.代码演示

代码如下:

package org.framework.modules.system.paramsUtil;

import com.alibaba.fastjson.JSONObject;
import org.framework.common.util.encryption.AesEncryptUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;

@WebFilter(urlPatterns = "/*")
// @WebFilter(filterName = "testFilter", urlPatterns = "/*", 
//        initParams = @WebInitParam(name = "noFilterUrl", value = "/test"))
public class ParamsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	// TODO 此处写具体的处理逻辑
        ServletRequest requestWrapper = null;
        HashMap paramsOld = new HashMap(request.getParameterMap());
        if(!ObjectUtils.isEmpty(paramsOld)){
            JSONObject json = (JSONObject) JSONObject.toJSON(paramsOld);
            if(json.containsKey("xxxcryptparams")){
                try {
                    String ss = json.getString("xxxencryptparams");
                   	...
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(request instanceof HttpServletRequest) {
                    requestWrapper = new RequestWrapper((HttpServletRequest) request,json);
                }
            }
        }
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }

    @Override
    public void destroy() {

    }
}
@SpringBootApplication
@ServletComponentScan
public class JeecgApplication {

  public static void main(String[] args) {
  ...
  }
}

四、Spring Boot过滤器方式2,使用FilterRegistrationBean

这种方式,适合过滤器的具体类已经写好的情况,这里做一下拦截。
可以自定义类,也可以是导入第三方的jar写好的类。

1.自定义类演示

注意,这个自定义类,也不能加@Component或@Configuration注解,加了就会初始化Filter了,过滤全部的路径了。

package org.framework.modules.system.paramsUtil;

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

public class ParamsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	// TODO 过滤器逻辑
         chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

@Bean
public FilterRegistrationBean<OrderFilter> orderFilter() {
    FilterRegistrationBean<OrderFilter> filter = new FilterRegistrationBean<>();
    filter.setName("paramsFilter");
    filter.setFilter(new ParamsFilter());
    // 指定优先级
    filter.setOrder(-1);
    return filter;
}

2.第三方jar演示

与web.xml配套:

package org.framework.modules.bsp.filter;

import org.xxx.AgentAuthzBaseRoleFilter;
import org.xxx.AgentSessionIntegrationFilter;
import org.xxx.SpFilterWrapper;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

@Configuration
public class MyBspFilter {
    /**
     * 注册registerSPDispacher
     */
    @Bean
    public FilterRegistrationBean registerSPDispacher() {
        FilterRegistrationBean registration  = new FilterRegistrationBean();

        registration.setFilter(new SpFilterWrapper());
        registration.addUrlPatterns(new String[] {"*.jsp","/service/*","/SAML2/*"});
        registration.setName("SPDispacher");
        registration.setOrder(1);  //值越小,Filter越靠前。

        return registration;
    }

    /**
     * 注册SessionIntegrationFilter
     */
   @Bean
    public FilterRegistrationBean registerSessionIntegrationFilter() {
        FilterRegistrationBean registration  = new FilterRegistrationBean();

        registration.setFilter(new AgentSessionIntegrationFilter());
        registration.addUrlPatterns("/*");
        registration.setName("SessionIntegrationFilter");
        registration.setOrder(2);  //值越小,Filter越靠前。

        return registration;
    }

    /**
     * 注册SessionIntegrationFilter
     */
    @Bean
    public FilterRegistrationBean registerAuthorizationFilter() {
        FilterRegistrationBean registration  = new FilterRegistrationBean();

        registration.setFilter(new AgentAuthzBaseRoleFilter());
        registration.addUrlPatterns("/service/*");
        registration.setName("AuthorizationFilter");
        registration.setOrder(3);  //值越小,Filter越靠前。

        return registration;
    }
}

五、Spring Boot过滤器方式3,实现ServletContextInitializer接口

这种方式,适合过滤器的具体类已经写好的情况,这里做一下过滤。
可以自定义类,也可以是导入第三方的jar写好的类。此处以与web.xml配套的第三方jar演示。

1.代码演示

与web.xml配套:

package org.framework.modules.bsp.filter;

import org.xxx.AgentAuthzBaseRoleFilter;
import org.xxx.AgentSessionIntegrationFilter;
import org.xxx.service.SpFilterWrapper;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Configuration;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

@Configuration
public class MyWebApplicationInitializer implements ServletContextInitializer {
    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        FilterRegistration.Dynamic sPDispacher = sc.addFilter("SPDispacher", SpFilterWrapper.class);
        sPDispacher.addMappingForUrlPatterns(null, false, "*.jsp");
        sPDispacher.addMappingForUrlPatterns(null, false, "/service/*");
        sPDispacher.addMappingForUrlPatterns(null, false, "/SAML2/*");

        FilterRegistration.Dynamic sessionIntegrationFilter = sc.addFilter("SessionIntegrationFilter", AgentSessionIntegrationFilter.class);
        sessionIntegrationFilter.addMappingForUrlPatterns(null, false, "/*");


        FilterRegistration.Dynamic authorizationFilter = sc.addFilter("AuthorizationFilter", AgentAuthzBaseRoleFilter.class);
        authorizationFilter.addMappingForUrlPatterns(null, false, "/service/*");
    }
}


总结

这3中方式,都是测过够写出来的。我最终使用的是 FilterRegistrationBean 方式。如果以后对顺序有要求,可以灵活的修改。v:wang13191319

你可能感兴趣的:(Spring,Boot,filter,spring,boot,java,spring)