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)

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券