Springboot项目实现过滤器功能
核心类
Filter
Filter接口的全限定类名是javax.servlet.Filter,该接口有三个方法,分别是
1、init(...):用于初始化Filter;
2、doFilter(...):过滤请求和拦截响应信息的具体实现在这个方法里;
3、destroy(...):Filter对象被销毁时触发,主要用于做一些收尾工作,如资源的释放等;
FilterConfig
FilterConfig接口的全限定类名是javax.servlet.FilterConfig,该接口主要有四个方法,分别是:
1、getFilterName() 获取Filter的名字;
2、getServletContext() 获取ServletContext对象(即application);
3、getInitParameter() 获取Filter的初始化参数;
4、getInitParameterNames() 获取所有初始化参数的名字;
FilterChain
FilterChainr接口的全限定类名是javax.servlet.FilterChain,该接口只有一个方法,是doFilter()方法,用于调用Filter链上的下一个过滤器,
如果当前过滤器为最后一个或只有一个过滤器,则该过滤器则将请求发送到目标资源。
MyFilter2是自己实现的过滤器,实现了Filter接口;Filter接口依赖FilterChain接口和FilterConfig接口,
其中FilterChain接口的实现类是org.apache.catalina.core.ApplicationFilterChain,
FilterConfig接口的实现类是org.apache.catalina.core.ApplicationFilterConfig;
实现方式
Springboot项目中一般有两种方式:
1、@WebFilter注解,即javax.servlet.annotation.WebFilter;
2、FilterRegistrationBean,即org.springframework.boot.web.servlet.FilterRegistrationBean;
两种方式,都需要在启动类上增加注解@ServletComponentScan,用于开启servlet相关bean的扫描,其中包含有过滤器(Filter);
1 2 3 4 5 6 7 | @SpringBootApplication @ServletComponentScan public class FanfuApplication { public static void main(String[] args) { SpringApplication.run(FanfuApplication. class , args); } } |
代码实现
1、WebFilter注解里,定义一下过滤器的名字,以及要对哪些请求进行过滤,“/*”表示对所有的请求都过滤,在实际业务中,可具体对待;
如果在初始化的时候,需要携带一些初始化的参数,可以在initParams属性上,使用@WebInitParam注解来定义初始化参数名称和具体的值,这些参数可以在filter对象初始化的时候获取到;
MyFIlter1和MyFIlter2使用的注解方式定义的过滤器;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @Slf4j @WebFilter (filterName = "myFilter1" , urlPatterns = "/*" , initParams = { @WebInitParam (name = "creator" , value = "fanfu" )}) public class MyFilter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info( "//myFilter1初始化开始" ); String creator = filterConfig.getInitParameter( "creator" ); log.info( "//初始化参数creator:{}" ,creator); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info( "//myFilter1开始执行" ); chain.doFilter(request, response); log.info( "//myFilter1结束执行" ); } @Override public void destroy() { log.info( "//myfilter1被销毁" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Slf4j @WebFilter (filterName = "myFilter2" , urlPatterns = "/*" ) public class MyFilter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info( "//myFilter2初始化开始" ); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info( "//myFilter2开始执行" ); chain.doFilter(request, response); log.info( "//myFilter2结束执行" ); } @Override public void destroy() { log.info( "//myFilter2被销毁" ); } } |
2、FilterRegistrationBean方式
在Springboot项目的配置类中,使用FilterRegistrationBean来包装自定义的过滤器,这种方式的最大好处就是可以自定义过滤器的执行顺序,数字越小,执行时的优先级就越高;
MyFIlter3和MyFIlter4是使用FilterRegistrationBean方式定义的过滤器;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Configuration public class WebConfig { @Bean public FilterRegistrationBean filterRegistration1() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter( new MyFilter3()); filterRegistrationBean.addUrlPatterns( "/*" ); //定义过滤器对哪些请求路径进行过滤,/*表示对所有请求都过滤 filterRegistrationBean.setOrder( 2 ); //定义过滤器的执行优先级,数据越小优先级越高 return filterRegistrationBean; } @Bean public FilterRegistrationBean filterRegistration2() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter( new MyFilter4()); filterRegistrationBean.addUrlPatterns( "/*" ); filterRegistrationBean.setOrder( 1 ); return filterRegistrationBean; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Slf4j public class MyFilter3 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info( "//MyFilter3初始化开始" ); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info( "//MyFilter3开始执行" ); chain.doFilter(request,response); log.info( "//MyFilter3结束执行" ); } @Override public void destroy() { log.info( "//MyFilter3被销毁" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Slf4j public class MyFilter4 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info( "//MyFilter4初始化开始" ); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info( "//MyFilter4开始执行" ); chain.doFilter(request,response); log.info( "//MyFilter4结束执行" ); } @Override public void destroy() { log.info( "//MyFilter4被销毁" ); } } |
未定义myFilter3、myFilter4的执行优先级,即采取自然排序时的执行结果:在请求前myFilter3的执行时机早于myFilter4,响应后myFilter3的执行时机要晚于myFilter4;
定义myFilter4的优先级高于myFilter3时,执行结果:在请求前myFilter4的执行时机早于myFilter3,响应后的myFilter4的执行时机要晚于myFilter3;
总结
1、过滤器是用于SpringMVC项目中,即与servlet相关的项目;
2、过滤器的执行时机是在请求前和响应后,有两种实现方式,即@WebFilter注解和FilterRegistrationBean;
如果对过滤器的执行顺序没有限制要求,则可以使用第一种;
如果对过滤器的执行顺序有明确限制,则可以使用第二种;
3、如果有多个过滤器对象时,会形成一个过滤器链,过滤器的执行顺序是先进后出;
4、过滤器可以过滤请求和拦截响应,但是不能改变请求值和响应值;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix