0


SpringBoot——使用Filter过滤器

过滤器Filter可以在controller处理逻辑之前和之后加入一些其他逻辑,可以在controller之前进行验证和信息处理,或者在controller之后进行统计记录。过滤器可以设置过滤路径,多个过滤器也可以指定过滤顺序;

过滤器可以实现一个接口类javax.servlet.Filter:

实现接口中的三个方法:

  1. init:过滤器初始化操作,springboot启动的时候调用;
  2. doFilter:过滤处理逻辑;
  3. destroy:过滤器销毁操作,项目结束停止的时候调用;

注:doFilter方法里有个FilterChain参数,在过滤逻辑里需要手动调用chain.doFilter(request, response)才会往下处理其他过滤器和controller;

可以使用三种方法配置过滤器:

1.使用@Component过滤所有url地址

只需要实现Filter接口,实现接口里必要的doFilter方法(init和destroy方法是接口里的默认方法),实现类使用@Component修饰就可以了;

启动类,使用的默认配置,端口8080,本机ip是192.168.1.30:

/**
 * 2023年3月10日下午3:51:13
 */
package testspringboot.test8filter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author XWF
 *
 */
@SpringBootApplication
public class Test8Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(Test8Main.class, args);
    }

}

controller类:

/**
 * 2023年3月10日下午4:05:24
 */
package testspringboot.test8filter;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author XWF
 *
 */
@RestController
@RequestMapping("/filter")
public class MyController {

    @RequestMapping("/test")
    public String test1(String a) {
        System.out.println("_Controller_test1:" + a);
        return "test1";
    }
    
    @RequestMapping("/test/a")
    public String test2(String a) {
        System.out.println("_Controller_test2:" + a);
        return "test2";
    }
    
    @RequestMapping("/test/b")
    public String test3(String a) {
        System.out.println("_Controller_test3:" + a);
        return "test3";
    }
    
}

测试的Filter类:

/**
 * 2023年3月10日下午4:00:40
 */
package testspringboot.test8filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

/**
 * @author XWF
 *
 */
@Component
public class MyFilter1 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter1 init:" + filterConfig.getFilterName());
    }
    
    @Override
    public void destroy() {
        System.out.println("MyFilter1 destroy");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("过滤所有Controller之前");
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        System.out.println("RequestURL=" + httpRequest.getRequestURL());
        chain.doFilter(request, response);
        System.out.println("过滤所有Controller之后");
    }

}

从启动日志就可以看到,项目启动的时候过滤器就是初始化:

http测试使用的是Apipost工具,执行几次测试:

程序输出日志:

可以看到所有的路径都会被过滤器过滤,没有controller处理的路径也会被过滤;

结束项目,过滤器就会执行销毁方法:

2.使用@Configuration配置过滤器

首先需要实现Filter接口(不使用@Component注解),然后需要一个@Configuration配置类,配置类里使用@Bean手动定义注入FilterRegistrationBean类,使用FilterRegistrationBean类设置自定义的Filter实现类和一些设置项;

两个Filter实现类:

/**
 * 2023年3月13日下午4:19:00
 */
package testspringboot.test8filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author XWF
 *
 */
public class MyFilter2ForConf implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("ConfFilter2 init " + filterConfig.getFilterName());
        System.out.println("ConfFilter2 init flag param = " + filterConfig.getInitParameter("flag")); //获得初始化参数
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("配置的MyConfFilter2 start");
        chain.doFilter(request, response);
        System.out.println("配置的MyConfFilter2 end");
    }

}
/**
 * 2023年3月14日上午10:00:53
 */
package testspringboot.test8filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * @author XWF
 *
 */
public class MyFilter3ForConf implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("ConfFilter3 init " + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("配置的MyConfFilter_3 start");
        chain.doFilter(request, response);
        System.out.println("配置的MyConfFilter_3 end");
    }

}

过滤器配置类:

/**
 * 2023年3月14日上午9:30:13
 */
package testspringboot.test8filter;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author XWF
 *
 */
@Configuration
public class FilterConf {

    @Bean
    public FilterRegistrationBean<MyFilter2ForConf> a() {
        FilterRegistrationBean<MyFilter2ForConf> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setEnabled(true);    //是否启用注入过滤器
        filterRegistrationBean.setFilter(new MyFilter2ForConf());    //设置过滤器
        filterRegistrationBean.setOrder(2);        //设置过滤器顺序,小的在前
        filterRegistrationBean.setName("My_Conf_Filter");    //设置过滤器名字
        List<String> urlPatterns = new ArrayList<>();
        urlPatterns.add("/filter/test/a");
        filterRegistrationBean.setUrlPatterns(urlPatterns);        //设置过滤路径
        filterRegistrationBean.addUrlPatterns("/filter/x", "/filter/y");    //添加过滤路径
//        filterRegistrationBean.setInitParameters(initParameters);    //设置初始化参数
        filterRegistrationBean.addInitParameter("flag", "ok");        //添加设置初始化参数
        return filterRegistrationBean;
    }
    
    @Bean
    public FilterRegistrationBean<MyFilter3ForConf> b() {
        FilterRegistrationBean<MyFilter3ForConf> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new MyFilter3ForConf());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/filter/test/*");
        return filterRegistrationBean;
    }
    
}

启动项目,三个过滤器都会init:

访问controller测试:

Order为1的filter3先过滤,Order为2的filter2在后,先使用@Configuration配置的过滤器过滤,再使用@Component的过滤器,另外controller之前过滤器是顺序执行,controller之后则是倒序执行,即由外向内进入再由内向外退出过滤器;

3.使用@WebFilter和@ServletComponentScan配置过滤器

在Filter实现类上使用@WebFilter注解,在启动类上使用@ServletComponentScan注解设置扫描路径;(该方法无法设置过滤顺序,默认按类名排序)

启动类添加@ServletComponentScan注解:

/**
 * 2023年3月10日下午3:51:13
 */
package testspringboot.test8filter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * @author XWF
 *
 */
@SpringBootApplication
@ServletComponentScan(basePackages = {"testspringboot.test8filter"})
public class Test8Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(Test8Main.class, args);
    }

}

过滤器实现类:

/**
 * 2023年3月14日上午11:09:18
 */
package testspringboot.test8filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

/**
 * @author XWF
 *
 */
@WebFilter(value = "/filter/test/a", urlPatterns = {}, asyncSupported = false, description = "测试过滤器", 
        dispatcherTypes = {DispatcherType.REQUEST},displayName = "displayName", filterName = "注解filter4", 
        initParams = {@WebInitParam(name = "str", value = "HELLO")}, 
        largeIcon = "", smallIcon = "", servletNames = "")
public class MyFilter4ForAnnotation implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Annotation Filter4 init: " + filterConfig.getFilterName());
        System.out.println("Annotation Filter4 paramNames: ");
        Enumeration<String> ele = filterConfig.getInitParameterNames();        //所有初始化参数名字
        while(ele.hasMoreElements()) System.out.println("\t" + ele.nextElement());
        System.out.println("Annotation Filter4 param str: " + filterConfig.getInitParameter("str"));
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("注解filter4 start");
        chain.doFilter(request, response);
        System.out.println("注解filter4 stop");
    }

}
/**
 * 2023年3月14日上午11:09:35
 */
package testspringboot.test8filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/**
 * @author XWF
 *
 */
@WebFilter("/filter/test/*")
public class MyFilter5ForAnnotation implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Annotation Filter5 init: " + filterConfig.getFilterName());    //注解Filter默认名是类全路径
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("注解filter5 start");
        chain.doFilter(request, response);
        System.out.println("注解filter5 stop");
    }

}

启动测试,过滤器初始化:

测试:

先执行@Configuration配置的过滤器,再执行@WebFilter注解配置的过滤器,最后执行@Component配置的过滤器(这也是默认order顺序);

@Component+@Order也能设置过滤器顺序;

在使用@WebFilter的过滤器上不要配置@Component@Configuration,否则会使@WebFilter里的过滤路径失效,将过滤所有路径;

过滤器执行顺序:

  • 先执行设置order的(只有@Configuration和@Component两类) - 按照设置的order从小到大执行 - order相同的,先按照@Configuration => @Component排序,相同配置类型里按照类名排序执行;
  • 后执行默认order的 - 按照@Configuration => @WebFilter => @Component三种类型顺序执行,相同配置类型里按照类名排序执行;
标签: springboot filter

本文转载自: https://blog.csdn.net/FlyLikeButterfly/article/details/129488252
版权归原作者 FlyLikeButterfly 所有, 如有侵权,请联系我们删除。

“SpringBoot——使用Filter过滤器”的评论:

还没有评论