Spring Boot Filter过滤器介绍

x33g5p2x  于2022-09-23 转载在 Spring  
字(12.4k)|赞(0)|评价(0)|浏览(527)

本文将介绍 Spring Boot Filter 示例。可以使用 FilterRegistrationBean 类或 @Component 注释或 @ServletComponentScan 注释来注册过滤器。 FilterRegistrationBean 将一个过滤器注册为 Spring bean,它提供了添加 URL 映射、设置过滤器顺序等方法。当我们使用 Spring @Component 注册过滤器时,我们可以使用 Spring @Order 注释设置过滤器顺序,但无法更改默认 URL 映射这个案例。当我们使用 @ServletComponentScan 注册过滤器时,我们的过滤器必须使用 @WebFilter 注释进行注释,并且我们可以使用其 urlPatterns 属性添加 URL 映射,但在这种情况下我们不能设置过滤器顺序。 @ServletComponentScan 仅在使用嵌入式服务器时有效。在本文中,我们将提供完整的 Spring Boot Filter 示例,其中包含过滤器、servlet 和 Spring 控制器。

1. 使用的技术

示例中使用的技术

  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

<?xml version="1.0" encoding="UTF-8"?>
&ltproject xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	
	&ltmodelVersion&gt4.0.0</modelVersion>
	&ltgroupId&gtcom.concretepage</groupId>
	&ltartifactId&gtspring-boot-app</artifactId>
	&ltversion&gt0.0.1-SNAPSHOT</version>
	&ltpackaging&gtjar</packaging>
	&ltname&gtspring-boot-app</name>
	&ltdescription&gtSpring Boot Application</description>

	&ltparent>
	   &ltgroupId&gtorg.springframework.boot</groupId>
	   &ltartifactId&gtspring-boot-starter-parent</artifactId>
	   &ltversion&gt2.0.3.RELEASE</version>
	   &ltrelativePath/>
	</parent>
	&ltproperties>
	   &ltjava.version&gt9</java.version>
	</properties>
	&ltdependencies>
	   &ltdependency>
	      &ltgroupId&gtorg.springframework.boot</groupId>
	      &ltartifactId&gtspring-boot-starter-web</artifactId>
	   </dependency>	
           &ltdependency>
              &ltgroupId&gtorg.springframework.boot</groupId>
              &ltartifactId&gtspring-boot-devtools</artifactId>
              &ltoptional&gttrue</optional>
           </dependency>
	</dependencies> 
	&ltbuild>
	   &ltplugins>
	      &ltplugin>
	  	 &ltgroupId&gtorg.springframework.boot</groupId>
	 	 &ltartifactId&gtspring-boot-maven-plugin</artifactId>
	      </plugin>
	   </plugins>
	</build>
</project>

3. 使用FilterRegistrationBean注册过滤器

FilterRegistrationBean 在 Servlet 3.0 + 容器中注册过滤器。 FilterRegistrationBean 将过滤器注册为 Spring bean。找到它的一些方法。
setFilter():设置过滤器对象。
addUrlPatterns():添加过滤器 URL 映射。
setOrder():设置过滤器顺序。

找到 JavaConfig 以注册 ABCFilterXYZFilter 类。
WebConfig.java

@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean&ltABCFilter> abcFilter() {
	   FilterRegistrationBean&ltABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean&ltXYZFilter> xyzFilter() {
	   FilterRegistrationBean&ltXYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   ------
}

3.1 过滤 URL 模式

要添加过滤器 URL 模式,我们可以使用 FilterRegistrationBeanaddUrlPatterns()setUrlPatterns() 方法。假设我们要使用 addUrlPatterns() 将 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:这是最低优先级。

订单号越低,优先级越高。查找示例优先顺序。
示例 1:

Ordered.LOWEST_PRECEDENCE -2 > Ordered.LOWEST_PRECEDENCE -1

示例 2:

Ordered.HIGHEST_PRECEDENCE +1 > Ordered.HIGHEST_PRECEDENCE +2

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

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)

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

5. 使用@ServletComponentScan 和@WebFilter 注册过滤器

要在 Spring Boot 中注册过滤器,我们可以使用 @ServletComponentScan 并且过滤器应该使用 @WebFilter 注释进行注释。我们需要将 @ServletComponentScan@Configuration@SpringBootApplication 注释一起使用。只有在使用嵌入式 Web 服务器时,Spring Boot 中的 @ServletComponentScan 才会扫描带有 @WebServlet 注释的 servlet、带有 @WebFilter 注释的过滤器和带有 @WebListener 注释的侦听器。假设我们有两个用 @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 类 with@ServletComponentScan 扫描上述过滤器。
SpringBootAppStarter.java

package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

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

过滤 URL 模式
注释 @WebFilter 具有属性 urlPatterns 来映射 URL,如下所示。

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

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

6. 完整示例:Spring Boot Filter Mapping with FilterRegistrationBean

我们将在此处提供带有 FilterRegistrationBean 类的 Spring Boot 过滤器完整示例。我们将在演示应用程序中使用方法创建两个过滤器、两个 servlet 和一个 Spring 控制器。我们将使用 FilterRegistrationBean 注册过滤器,并在 JavaConfig 中使用 ServletRegistrationBean 类注册 servlet。现在找到完整的例子。
找到演示应用程序的项目结构。

现在找到 Java 文件。
ABCFilter.java

package com.concretepage.filters;
import java.io.IOException;
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;

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() {
	}
}

XYZFilter.java

package com.concretepage.filters;
import java.io.IOException;
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;

public class XYZFilter 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 XYZFilter: "+ req.getRequestURI());
		chain.doFilter(request, response);
	}
	@Override
	public void destroy() {
	}
}

HelloCountryServlet.java

package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloCountryServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	    doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
	    out.println("&lth3&gtHello India!</h3>");	
	}
}

HelloStateServlet.java

package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloStateServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	   doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
           response.setContentType("text/html");
           PrintWriter out = response.getWriter();
	   out.println("&lth3&gtHello Uttar Pradesh!</h3>");	
	}
}

WebConfig.java

package com.concretepage;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import com.concretepage.filters.ABCFilter;
import com.concretepage.filters.XYZFilter;
import com.concretepage.servlets.HelloCountryServlet;
import com.concretepage.servlets.HelloStateServlet;

@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean&ltABCFilter> abcFilter() {
	   FilterRegistrationBean&ltABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean&ltXYZFilter> xyzFilter() {
	   FilterRegistrationBean&ltXYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   
   //Register HelloCountryServlet   
   @Bean	
   public ServletRegistrationBean&ltHelloCountryServlet> countryServlet() {
	   ServletRegistrationBean&ltHelloCountryServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloCountryServlet());
	   servRegBean.addUrlMappings("/app/country/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }
   //Register HelloStateServlet   
   @Bean	
   public ServletRegistrationBean&ltHelloStateServlet> stateServlet() {
	   ServletRegistrationBean&ltHelloStateServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloStateServlet());
	   servRegBean.addUrlMappings("/app/state/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }   
}

HelloWorldController.java

package com.concretepage.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {     
	
    @RequestMapping("/app/world")
    public String helloMsg() {
    	String msg = "Hello World!";
        return msg;
    }
}

SpringBootAppStarter.java

package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootAppStarter {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAppStarter.class, args);
    }
}

7. 测试应用

我们可以通过以下方式运行我们的 Spring Boot 应用程序。
1。使用 Maven 命令:下载项目源代码。使用命令提示符转到项目的根文件夹并运行命令。

mvn spring-boot:run

Tomcat 服务器将被启动。

2。使用 Eclipse:使用文章末尾给出的下载链接下载项目源代码。将项目导入eclipse。使用命令提示符,转到项目的根文件夹并运行。

mvn clean eclipse:eclipse

然后在eclipse中刷新项目。单击 Run as -> Java Application 运行主类 SpringBootAppStarter。 Tomcat 服务器将被启动。

3。使用 Executable JAR:使用命令提示符,转到项目的根文件夹并运行命令。

mvn clean package

我们将在目标文件夹中获得可执行的 JAR spring-boot-app-0.0.1-SNAPSHOT.jar。将此 JAR 运行为

java -jar target/spring-boot-app-0.0.1-SNAPSHOT.jar

Tomcat 服务器将被启动。

现在我们准备好测试应用程序了。运行以下 URL。

http://localhost:8080/app/country

我们将在控制台中获得以下输出。
输出

Inside XYZFilter: /app/country
Inside ABCFilter: /app/country

运行以下 URL。

http://localhost:8080/app/state

输出

Inside XYZFilter: /app/state
Inside ABCFilter: /app/state

运行以下 URL。

http://localhost:8080/app/world

输出

Inside XYZFilter: /app/world
Inside ABCFilter: /app/world

相关文章