SpringBoot过滤器Filter

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

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

1.使用FilterRegistrationBean类:提供增加URL映射的方法,设置过滤器顺序。

2. @Component 注释:无法改变默认的URL映射,通过@Order注释设置过滤器顺序。

3. @ServletComponentScan 注释:过滤器必须使用@WebFilter注释,能够通过它的urlPattern属性增加URL映射,但是无法设置过滤器顺序,只在使用嵌入服务器才有效。

1. 使用的技术Technologies Used

使用了下面的技术栈:. 

1. Java 9 

2. Spring 5.0.7.RELEASE 

3. Spring Boot 2.0.3.RELEASE 

4. Maven 3.5.2 

5. 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;

@Configuration
public 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)
@Component
public class ABCFilter implements Filter { ------
}

XYZFilter.java

@Order(Ordered.LOWEST_PRECEDENCE -2)
@Component
public 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
@SpringBootApplication
public 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。.

 

Spring cloud