Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
当前回答
更新:2022-05-29:
在Spring Boot 1.5.8中有两种简单的方法可以做到这一点。发布,不需要XML。
第一个方法:
如果你没有任何特定的URL模式,你可以像这样使用@Component(完整的代码和细节在这里https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/3_spring-boot-filter,看看README.txt开始):
@Component
public class ExampleFilter implements Filter {
...
}
第二种方式:
如果你想使用URL模式,你可以像这样使用@WebFilter(完整的代码和细节在这里https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/4_spring-boot-filter-urlpattern,看看README.txt开始):
@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter {
...
}
但是你也需要在你的@SpringBootApplication类中添加@ServletComponentScan注释:
@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}
注意@Component是Spring的注释,而@WebFilter不是。@WebFilter是Servlet 3注释。
这两种方法都只需要在pom.xml中有一个基本的Spring Boot依赖项(不需要显式地嵌入Tomcat jasper)
<?xml version="1.0" encoding="UTF-8"?>
<project 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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<groupId>com.surasint.example</groupId>
<artifactId>spring-boot-04</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
警告:第一种方法,如果Spring Boot中的Controller返回到JSP文件,请求将通过过滤器两次。
而在第二种方式中,请求将只通过筛选器一次。
我更喜欢第二种方式,因为它更类似于Servlet规范中的默认行为。
其他回答
此过滤器还将帮助您允许跨源访问
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "20000");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
public void destroy() {}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
没有特殊的注释来表示servlet筛选器。您只需声明一个Filter类型的@Bean(或FilterRegistrationBean)。在Boot自己的EndpointWebMvcAutoConfiguration中有一个例子(为所有响应添加自定义头);
如果你只声明一个过滤器,它将被应用到所有的请求。如果您还添加了一个FilterRegistrationBean,您可以另外指定要应用的单个servlet和url模式。
注意:
从Spring Boot 1.4开始,FilterRegistrationBean不再弃用,而是简单地将包从org.springframework. Boot .context. embedd.filterregistrationbean移动到org.springframework.boot.web.servlet.FilterRegistrationBean
下面是一个在Spring Boot MVC应用程序中包含自定义过滤器的方法示例。确保在组件扫描中包含该包:
package com.dearheart.gtsc.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.HttpServletResponse;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
public class XClacksOverhead implements Filter {
public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
chain.doFilter(req, res);
}
@Override
public void destroy() {}
@Override
public void init(FilterConfig arg0) throws ServletException {}
}
众所周知,Spring Boot是开发web应用程序或独立应用程序的一种极好的方式,具有最低的配置和独立的设置。
这就是我如何在Spring Boot应用程序中实现web过滤器开发的
我的SpringBootApp规格:
Spring Boot版本:2.0.4.RELEASE Java版本:8.0 Servlet规范:Servlet 3.0(强制性和重要)
我以以下方式声明了我的web过滤器,遵循Servlet规范3.0
这是定义过滤器作为基于web.xml定义的替代品的编程方式。
“@Webfilter”注释将在部署期间由容器处理。它所在的Filter类将根据配置创建,并应用于URL模式javax.servlet.Servlets和javax.servlet.DispatcherTypes。
要完全避免Web.xml,实现“可部署”的WebApp:
要将SpringBoot应用程序部署为“Traditional WAR”,应用程序类应该扩展SpringBootServletInitializer。
注意:
SpringBootServletInitializer是web.xml的“编程实现”,参考了Servlet 3.0+规范,它需要WebApplicationInitializer的实现。
因此,SpringBootApplication不需要“web.xml”作为它的应用程序类(在扩展SpringBootServletInitializer之后)。它扫描
@WebFilter, @WebListener鸭 @WebServlet。
注释@ServletComponentScan
这个注释允许扫描带有@WebFilter, @WebListener和@WebServlet注释的web组件的基本包。
由于嵌入式容器不支持@WebServlet、@WebFilter和@WebListener注解,Spring Boot在很大程度上依赖于嵌入式容器,引入了这个新的注解@ServletComponentScan来支持一些使用这三种注解的依赖JAR文件。
扫描只在使用嵌入式Servlet容器时执行。
下面是我的Spring Boot应用程序类定义:
自定义Servlet初始化器:
这里:我定义了一个自定义类:“ServletInitializer”,它扩展了class: SpringBootServletInitializer。
如前所述,SpringBootServletInitializer负责扫描注释:
@WebFilter, @WebListener鸭 @WebServlet。
因此Spring Boot应用程序类应该这样做
扩展类:SpringBootServletInitializer或 扩展扩展该类的自定义类:SpringBootServletInitializer
过滤器,顾名思义,用于对资源的请求或资源的响应执行过滤,或同时对两者执行过滤。Spring Boot提供了一些选项来在Spring Boot应用程序中注册自定义过滤器。让我们看看不同的选项。
1. 定义Spring Boot过滤器和调用顺序
实现Filter接口,在Spring Boot中创建一个新的过滤器。
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating Custom filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("Logging Request {} : {}", request.getMethod(), request.getRequestURI());
// Call next filter in the filter chain
filterChain.doFilter(request, response);
LOGGER.info("Logging Response :{}", response.getContentType());
}
@Override
public void destroy() {
// TODO: 7/4/2018
}
}
让我们快速看一下上面代码中的一些要点
@Component注释注册的过滤器。 为了以正确的顺序触发过滤器,我们需要使用@Order注释。 @ component @Order (1) 公共类CustomFirstFilter实现了Filter { } @ component @Order (2) 公共类CustomSecondFilter实现了Filter { }
在上面的代码中,CustomFirstFilter将在CustomSecondFilter之前运行。
数字越低,优先级越高
2. URL模式
如果基于约定的映射不够灵活,我们可以使用FilterRegistrationBean对应用程序进行完全控制。在这里,不要为过滤器类使用@Component注释,而是使用FilterRegistrationBean注册过滤器。
public class CustomURLFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating CustomURLFilter filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("This Filter is only called when request is mapped for /customer resource");
// Call the next filter in the filter chain
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
使用FilterRegistrationBean注册自定义过滤器。
@Configuration
public class AppConfig {
@Bean
public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
CustomURLFilter customURLFilter = new CustomURLFilter();
registrationBean.setFilter(customURLFilter);
registrationBean.addUrlPatterns("/greeting/*");
registrationBean.setOrder(2); // Set precedence
return registrationBean;
}
}