解决springboot中配置过滤器以及可能出现的问题
在springboot添加过滤器有两种方式:
1、通过创建FilterRegistrationBean的方式(建议使用此种方式,统一管理,且通过注解的方式若不是本地调试,如果在filter中需要增加cookie可能会存在写不进前端情况)
2、通过注解@WebFilter的方式
通过创建FilterRegistrationBean的方式创建多个filter以及设置执行顺序:
1、创建两个实现Filter接口的类TestFilter1 、TestFilter2
package com.aoxun.core.filter; 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; public class TestFilter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); } @Override public void destroy() {} }
package com.aoxun.core.filter; 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; public class TestFilter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); } @Override public void destroy() {} }
2、创建配置类
有多个filter就创建多个FilterRegistrationBean ,若需注明filter的执行顺序,可通过registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE - 1)配置,值越大,执行顺序越靠后
package com.aoxun.config.web; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.aoxun.core.filter.TestFilter1; import com.aoxun.core.filter.TestFilter2; /** * filter配置 * @author zcj * */ @Configuration public class FilterConfig2 { @Bean public FilterRegistrationBean companyUrlFilterRegister() { FilterRegistrationBean registration = new FilterRegistrationBean(); //注入过滤器 registration.setFilter(new TestFilter1()); //拦截规则 registration.addUrlPatterns("/*"); //过滤器名称 registration.setName("testFilter1"); //过滤器顺序 registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); return registration; } @Bean public FilterRegistrationBean outLinkSecurityFilterRegister() { FilterRegistrationBean registration = new FilterRegistrationBean(); //注入过滤器 registration.setFilter(new TestFilter2()); //拦截规则 registration.addUrlPatterns("/*"); //过滤器名称 registration.setName("testFilter2"); //过滤器顺序 registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE - 1); return registration; } }
通过注解@WebFilter的方式
1、在启动类上增加@ServletComponentScan注解,自动扫描带有过滤器注解的包
2、在类上使用@WebFilter
package com.aoxun.core.filter; 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; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.annotation.Order; @WebFilter(filterName="testFilter1",urlPatterns= {"/*"}) public class TestFilter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
注:经测试,@Order并不能实现过滤器排序功能,在springboot中注解的方式增加过滤器可通过修改过滤器文件名称的方式排序,如上的过滤器TestFilter1在TestFilter2前。
补充知识:SpringBoot2.1.x,集成Filter过滤器的三种方式,包含OncePerRequestFilter方式
一)Filter过滤器简介
主要作用:Filter使用户可以改变一个request和修改一个response,它能够在一个request到达servlet之前预处理request,也可以在response离开servlet时处理response。例如收集数据和包装数据,并进行处理。
1、Filter是依赖Servlet容器的,如Tomcat。
2、Filter对所有的请求起作用,并是在sevlet之前处理。可以理解成过滤器中包含拦截器,当一个请求过来,先进行过滤器处理,再看程序是否受理该请求。过滤器执行完后,程序中的拦截器再进行处理。
3、Filter只能处理HttpServletRequest和HttpServletResponse,底层是基于回调函数。
二)SpringBoot集成Filter过滤器
第一步:先创建一个maven项目,引入springboot的jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.oysept</groupId> <artifactId>springboot_filter</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.oysept.FilterApplication</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
添加一个application.yml配置文件,指定一个端口
server:
port: 8080
创建一个Demo测试接口
package com.oysept.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Demo Controller * @author ouyangjun */ @RestController public class DemoController { // 带参GET请求: http://localhost:8080/demo/get/param?param=111222333444 @RequestMapping(value = "/demo/get/param", method = RequestMethod.GET) public String getParam(@RequestParam(value = "param") String param) { System.out.println("=====>进入DemoController /demo/get/param"); return "/demo/get/param," + param; } }
第二步:使用@WebFilter注解方式,实现Filter过滤器
当使用@WebFilter、@WebServlet、@WebListener等注解时, 需要在springboot启动类中启用@ServletComponentScan注解指定扫描包。
package com.oysept.filter; import java.io.IOException; import java.util.Enumeration; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.core.env.Environment; import org.springframework.web.filter.OncePerRequestFilter; /** * 过滤器, 过滤所有地址 * 方式一: 使用@WebFilter、@WebServlet、@WebListener等注解时, 需要在springboot启动类中启用@ServletComponentScan注解指定扫描包 * 方式二: 结合@WebFilter和@Component注解一起使用, 但可能会同时注入两个bean, 可能会报错, 可在application.yml配置中启用同名Bean覆盖: spring.main.allow-bean-definition-overriding=true * @author ouyangjun */ @WebFilter(value = "/*", filterName = "oauthFilter") public class OAuthFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { System.out.println("====>进入OAuthFilter doFilterInternal过滤器===="); System.out.println("请求地址: " + request.getRequestURL()); System.out.println("GET请求参数: "); Enumeration<String> parameters = request.getParameterNames(); String parameterName = ""; while (parameters.hasMoreElements()) { parameterName = parameters.nextElement(); System.out.println("参数名称: " + parameterName + ", 值: " + request.getParameter(parameterName)); } // 工具类 //FilterConfig filterConfig = super.getFilterConfig(); //ServletContext servletContext = super.getServletContext(); //Environment environment = super.getEnvironment(); System.out.println("====>结束OAuthFilter doFilterInternal过滤器===="); filterChain.doFilter(request, response); } }
第三步:使用@Component注解方式,实现Filter过滤器
package com.oysept.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; /** * 过滤器通过@Component注解注册 * @author ouyangjun */ @Component public class PathFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 转换 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println("====>进入PathFilter doFilter过滤器===="); System.out.println("====>结束PathFilter doFilter过滤器===="); filterChain.doFilter(request, response); } }
第四步:通过@Bean注解方式,实现Filter过滤器
@Configuration注解:相当于spring中的<beans>标签
@Bean注解:相当于spring中<bean>标签
package com.oysept.config; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Configuration注解: 相当于spring中的<beans>标签 * @Bean注解: 相当于spring中<bean>标签 * @author ouyangjun */ @Configuration public class MyFilterConfig { @Bean public FilterRegistrationBean<MyFilter> testFilterRegistration() { FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new MyFilter()); registration.addUrlPatterns("/*"); // 配置过滤路径 registration.addInitParameter("paramName", "paramValue"); // 添加初始值 registration.setName("myFilter"); // 设置filter名称 registration.setOrder(1); // 请求中过滤器执行的先后顺序,值越小越先执行 return registration; } // 实现一个过滤器 public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 转换 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println("====>进入MyFilter doFilter过滤器===="); System.out.println("====>结束MyFilter doFilter过滤器===="); filterChain.doFilter(request, response); } } }
第五步:创建一个SpringBoot启动类,并通过@ServletComponentScan注解指定扫描的Filter实现类
package com.oysept; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.ServletComponentScan; /** * @ServletComponentScan注解不指定扫描包时, 默认扫描当前包和子包 * @author ouyangjun */ @SpringBootApplication @ServletComponentScan(basePackages = "com.oysept.filter") public class FilterApplication { public static void main(String[] args) { new SpringApplicationBuilder(FilterApplication.class).run(args); } }
启动main方法,在浏览器输入地址:http://localhost:8080/demo/get/param?param=111222333444
在控制台查看打印日志:
项目结构图:
以上这篇解决springboot中配置过滤器以及可能出现的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。