解决springboot中配置过滤器以及可能出现的问题

网友投稿 698 2022-11-22


解决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,底层是基于回调函数。

sepswzYVyz

二)SpringBoot集成Filter过滤器

第一步:先创建一个maven项目,引入springboot的jar

4.0.0

com.oysept

springboot_filter

0.0.1-SNAPSHOT

jar

org.springframework.boot

spring-boot-starter-parent

2.1.4.RELEASE

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-maven-plugin

com.oysept.FilterApplication

org.apache.tomcat.maven

tomcat7-maven-plugin

添加一个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 parameters = request.getParameterNames();

String parameterName = "";

while (parameters.hasMoreElements()) {

parameterName = parameters.nextElement();

System.out.println("参数名称: " + parameterName + ", 值: " + rsepswzYVyzequest.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中的标签

@Bean注解:相当于spring中标签

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中的标签

* @Bean注解: 相当于spring中标签

* @author ouyangjun

*/

@Configuration

public class MyFilterConfig {

@Bean

public FilterRegistrationBean testFilterRegistration() {

FilterRegistrationBean 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

在控制台查看打印日志:

项目结构图:


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot处理全局统一异常的实现
下一篇:IDEA如何自动生成serialVersionUID的设置
相关文章

 发表评论

暂时没有评论,来抢沙发吧~