转载

SpringBoot过滤器

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

原文  https://www.jdon.com/springboot/spring-filter.html
正文到此结束
Loading...