专栏首页Linyb极客之路SpringBoot过滤器Filter

SpringBoot过滤器Filter

这是Spring过滤器案例,过滤器能够实在正常功能之外实现类似插件功能。

过滤器通过三种方式实现:

  1. 使用FilterRegistrationBean类:提供增加URL映射的方法,设置过滤器顺序。
  2. @Component 注释:无法改变默认的URL映射,通过@Order注释设置过滤器顺序。
  3. @ServletComponentScan 注释:过滤器必须使用@WebFilter注释,能够通过它的urlPattern属性增加URL映射,但是无法设置过滤器顺序,只在使用嵌入服务器才有效。

1. 使用的技术Technologies Used

使用了下面的技术栈:.

  • Java 9
  • Spring 5.0.7.RELEASE
  • Spring Boot 2.0.3.RELEASE
  • Maven 3.5.2
  • Eclipse Oxygen

2. pom.xml

没有什么特别,主要是两个常用依赖,与Filter关系不大:

 <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-devtools</artifactId>        <optional>true</optional>    </dependency>

3. 使用FilterRegistrationBean注册过滤器

FilterRegistrationBean 能够在 Servlet 3.0 + 容器注册过滤器,作为一个Spring bean注册的. 它的一些方法如下:

  • setFilter(): 设置过滤器对象.
  • addUrlPatterns(): 增加 URL mappings.
  • setOrder(): 设置过滤器顺序.

下面是使用JavaConfig注册ABCFilter和XYZFilter 类.

WebConfig.java

package com.example.springfilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.Ordered;
@Configurationpublic class WebConfig {   //Register ABCFilter   @Bean   public FilterRegistrationBean<ABCFilter> abcFilter() {      FilterRegistrationBean<ABCFilter> filterRegBean = new FilterRegistrationBean<>();      filterRegBean.setFilter(new ABCFilter());      filterRegBean.addUrlPatterns("/app/*");      filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);      return filterRegBean;   }   //Register XYZFilter   @Bean   public FilterRegistrationBean<XYZFilter> xyzFilter() {      FilterRegistrationBean<XYZFilter> filterRegBean = new FilterRegistrationBean<>();      filterRegBean.setFilter(new XYZFilter());      filterRegBean.addUrlPatterns("/app/*");      filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);      return filterRegBean;   }} 

AbcFilter/XYZFilter其实是一个Java servlet的过滤器:

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.http.HttpServletRequest;import java.io.IOException;
public class ABCFilter implements Filter {   @Override   public void init(FilterConfig filterConfig) throws ServletException {   }   @Override   public void doFilter(ServletRequest request, ServletResponse response,                   FilterChain chain) throws IOException, ServletException {      HttpServletRequest req = (HttpServletRequest) request;      System.out.println("Inside ABCFilter: "+ req.getRequestURI());      chain.doFilter(request, response);   }   @Override   public void destroy() {   }}

3.1. 过滤URL模式

通过使用FilterRegistrationBean的 addUrlPatterns() 或 setUrlPatterns() 方法实现URL的过滤模式,比如对 /app1/* 和 /app2/* 过滤

filterRegBean.addUrlPatterns("/app1/*", "/app2/*"); 

如果使用 setUrlPatterns(), 如下:这是一次性的设置一个集合。.

filterRegBean.setUrlPatterns(Arrays.asList("/app1/*", "/app2/*")); 

3.2. 过滤器顺序

当我们使用FilterRegistrationBean实现过滤器, 能够使用setOrder() 设置舒心:

filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE); 
  • Ordered.HIGHEST_PRECEDENCE: 这是最高优先.
  • Ordered.LOWEST_PRECEDENCE: 这是最低优先

顺序号越低,优先权越高.

Example-1:

Ordered.LOWEST_PRECEDENCE -2 > Ordered.LOWEST_PRECEDENCE -1 

Example-2:

Ordered.HIGHEST_PRECEDENCE +1 > Ordered.HIGHEST_PRECEDENCE +2 

无序排列过滤器也是安全的,Spring boot提供默认的顺序,通常使用Ordered.LOWEST_PRECEDENCE.如果我们想在任何内置过滤器(如Spring安全过滤器)之前或之后运行我们的自定义过滤器,我们需要使用FilterRegistrationBean对它们进行排序。比如我们想在Spring安全过滤器之后运行我们的自定义过滤器,我们需要用FilterRegistrationBean为Spring安全过滤器创建自己的过滤器并指定顺序。

4. 使用@Component 和 @Order 实现过滤器

我们可以使用注册过滤器@Component并设置顺序@Order。创建一个实现Java的过滤器Filter,并使用Spring @Component对其进行注释,如下所示。

ABCFilter.java

@Order(Ordered.LOWEST_PRECEDENCE -1)@Componentpublic class ABCFilter implements Filter {  ------} 

XYZFilter.java

@Order(Ordered.LOWEST_PRECEDENCE -2)@Componentpublic class XYZFilter implements Filter {  ------} 

过滤器顺序

当我们使用@Component注册过滤器时,我们可以使用Spring @Order注释将过滤器顺序设置为

@Order(Ordered.LOWEST_PRECEDENCE) 

过滤器URL模式过滤无法使用 @Component

URL模式默认过滤器URL模式为"/*"。如果我们使用@Component注释注册过滤器,我们无法更改它。如果我们想要过滤URL映射,我们应该使用注册过滤器FilterRegistrationBean。

5. 使用 @ServletComponentScan 和 @WebFilter实现过滤器

要在Spring Boot中注册过滤器,我们可以使用@ServletComponentScan,过滤器应该注释@WebFilter注解。我们需要使用@ServletComponentScan与@Configuration或@SpringBootApplication注释组合。

@ServletComponentScan在Spring Boot中,将扫描带有@WebServlet注释的servlet ,带有注释的过滤器@WebFilter和@WebListener仅在使用嵌入式Web服务器时才会扫描到的侦听器。假设我们有两个带有@WebFilter以下注释的过滤器。.

ABCFilter.java

@WebFilter(urlPatterns="/app/*")public class ABCFilter implements Filter {  ------} 

XYZFilter.java

@WebFilter(urlPatterns="/app/*")public class XYZFilter implements Filter {  ------} 

现在使用Spring boot starter Main class @ServletComponentScan来扫描上面的过滤器。

SpringBootAppStarter.java

@ServletComponentScan@SpringBootApplicationpublic class SpringfilterApplication {
   public static void main(String[] args) {      SpringApplication.run(SpringfilterApplication.class, args);   }}

过滤器 URL模式

注释@WebFilter具有urlPatterns映射URL 的属性,如下所示。

@WebFilter(urlPatterns= {"/app1/*", "/app2/*"})public class ABCFilter implements Filter {   ------} 

无法使用 @WebFilter设置过滤顺序

当我们使用@WebFilterthen 注册过滤器时,我们无法在Spring Boot中对它们进行排序。@WebFilter不提供任何设置顺序的属性。我们也不能使用Spring @Order注释,因为Spring没有将@WebFilter注释类标识为Spring bean。@WebFilter是一个Java注释而不是Spring注释。如果我们想要设置顺序,我们应该使用注册我们的过滤器FilterRegistrationBean。.

本文分享自微信公众号 - Linyb极客之路(gh_c420b2cf6b47),作者:jdon

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 8种常见SQL错误用法,你中招了吗?

    分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time...

    lyb-geek
  • 学习微服务网关zuul,看这篇就够了

    Zuul包含了对请求的路由和过滤两个主要的功能,其中路由功能负责将外部的请求转发到具体的微服务实例上,是实现外部访问统一入口的基础上,而过滤功能则负责对请求的处...

    lyb-geek
  • SQL优化指南

    slow_launch_time:表示如果建立线程花费了比这个值更长的时间,slow_launch_threads 计数器将增加

    lyb-geek
  • Vue.js入门教程-过滤器

    (1)过滤器(Filters)提供了一种 执行文本转换的方法,比如说都转换成大写字母或者几乎做任何我们想做的事情。

    WEBING
  • Vue教程08(过滤器的使用)

    概念:   Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该...

    用户4919348
  • 2.2.1、Google Analytics高级应用——过滤器的应用

    过滤器用于限制和修改数据视图中包含的数据。可以使用过滤器实现以下目的:排除来自特定IP地址的流量,仅包含某个子网域或目录中的数据,或者将动态网页网址转换为可读的...

    GA小站
  • 如何高效地编写Envoy过滤器!第1部分

    Envoy是一个可编程的L3/L4和L7代理,支持当今的服务网格解决方案,包括Istio、AWS App mesh、Consul Connect等。Envoy的...

    CNCF
  • 【一分钟知识】try catch finally执行顺序,final finally finalize的区别

    final、finally、finalize的区别 final 如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstrac...

    java思维导图
  • 快速学习-主页面访问权限控制

    cwl_java

扫码关注云+社区

领取腾讯云代金券