前言
本文記錄一下在SpringBoot項目中是如何使用Filter過濾器
代碼、測試
Filter過濾器是servlet包下面的東西,因此我們不需要再額外引包
方法一
直接實現Filter接口,並使用@Component注解標注為組件自動注入bean
package cn.huanzi.qch.springbootfilter.filter; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println("TestFilter,"+request.getRequestURI()); //執行 filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
查看日志可以發現,SpringBoot已經幫我們注入了一個filter,攔截路徑是/*,攔截所有,如果我們需要進一步攔截具體的則需要我們自己在代碼里控制
方法二
實現Filter接口,用@WebFilter注解,指定攔截路徑以及一些參數,同時需要在啟動類使用@ServletComponentScan掃描帶@WebFilter、@WebServlet、@WebListener並將幫我們注入bean
package cn.huanzi.qch.springbootfilter.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //配置攔截路徑 @WebFilter(filterName = "testFilter",urlPatterns = {"/test"}) public class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println("TestFilter,"+request.getRequestURI()); //執行 filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
package cn.huanzi.qch.springbootfilter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; //自動掃描與當前類的同包以及子包 @ServletComponentScan @SpringBootApplication public class SpringbootFilterApplication { public static void main(String[] args) { SpringApplication.run(SpringbootFilterApplication.class, args); } }
查看日志發現,以及幫我們注入了testFilter,攔截路徑是/test
只指定攔截路徑,不設置filterName一樣可以注入
//配置攔截路徑 @WebFilter({"/test"})
方法三
當然了,我們也可以既使用@Component同時也使用@WebFilter
package cn.huanzi.qch.springbootfilter.filter; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //配置攔截路徑 @WebFilter(filterName = "testFilter",urlPatterns = {"/test"}) @Component public class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println("TestFilter,"+request.getRequestURI()); //執行 filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
package cn.huanzi.qch.springbootfilter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; //自動掃描與當前類的同包以及子包 @ServletComponentScan @SpringBootApplication public class SpringbootFilterApplication { public static void main(String[] args) { SpringApplication.run(SpringbootFilterApplication.class, args); } }
但是做會注入兩個bean,如果你的@WebFilter沒有指定filterName或者指定的名稱與類名相同,由於注入兩個相同名稱的bean,程序啟動報錯,叫我們修改其中一個的名字,或者啟用覆蓋bean
這里建議如果你硬要采用第三種方法,最好啟用覆蓋,因為改名將會注入兩個bean,處理邏輯一樣但攔截路徑不一樣,這並不是我們想要的,例如:
啟用覆蓋
#啟用覆蓋同名bean spring.main.allow-bean-definition-overriding=true
PS:這里額外說一點,如果我們采用第三種方法,@ServletComponentScan放在TestFilter類上@WebFilter也會被掃描到,不需要放在啟動類,第二種方法如果也這樣做就不行,估計是受到了@Component注解的影響
//配置攔截路徑 @WebFilter(filterName = "testFilter",urlPatterns = {"/test"}) @ServletComponentScan @Component public class TestFilter implements Filter
后記
Filter過濾器暫時先記錄到這,以后再進行補充
代碼開源
代碼已經開源、托管到我的GitHub、碼雲: