这是Spring过滤器案例,过滤器能够实在正常功能之外实现类似插件功能。
过滤器通过三种方式实现:
使用了下面的技术栈:.
没有什么特别,主要是两个常用依赖,与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>
FilterRegistrationBean 能够在 Servlet 3.0 + 容器注册过滤器,作为一个Spring bean注册的. 它的一些方法如下:
下面是使用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);
顺序号越低,优先权越高.
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安全过滤器创建自己的过滤器并指定顺序。
我们可以使用注册过滤器@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。
要在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。.