Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?

我想在我的项目中添加一个自定义过滤器。

Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。


当前回答

在Spring文档中,

嵌入式servlet容器——向应用程序中添加servlet、过滤器或监听器

要添加Servlet、过滤器或Servlet *监听器,请提供@Bean 定义。

例如:

@Bean
public Filter compressFilter() {
    CompressingFilter compressFilter = new CompressingFilter();
    return compressFilter;
}

将这个@Bean配置添加到@Configuration类中,过滤器将在启动时注册。

此外,您还可以使用类路径扫描添加servlet、过滤器和侦听器,

@WebServlet, @WebFilter和@WebListener注释类可以是 自动注册到嵌入的servlet容器 用@ServletComponentScan和注释@Configuration类 指定包含所需组件的包 登记。默认情况下,@ServletComponentScan将从包中扫描 注释类的。

其他回答

你可以在实现javax.servlet.Filter的类上使用@WebFilter javax.servlet.annotation.WebFilter:

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
}

然后使用@ServletComponentScan注册。

更新: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规范中的默认行为。

如果您使用Spring Boot + Spring Security,则可以在安全配置中执行此操作。

在下面的示例中,我在UsernamePasswordAuthenticationFilter之前添加了一个自定义过滤器(请参阅所有默认的Spring安全过滤器及其顺序)。

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired FilterDependency filterDependency;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(
                new MyFilter(filterDependency),
                UsernamePasswordAuthenticationFilter.class);
    }
}

还有筛选器类

class MyFilter extends OncePerRequestFilter  {
    private final FilterDependency filterDependency;

    public MyFilter(FilterDependency filterDependency) {
        this.filterDependency = filterDependency;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain)
        throws ServletException, IOException {

        // Filter
        filterChain.doFilter(request, response);
    }
}

没有特殊的注释来表示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

如果您想要设置一个第三方过滤器,您可以使用FilterRegistrationBean。

例如,等价的web.xml:

<filter>
     <filter-name>SomeFilter</filter-name>
        <filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/url/*</url-pattern>
    <init-param>
        <param-name>paramName</param-name>
        <param-value>paramValue</param-value>
    </init-param>
</filter-mapping>

这将是@Configuration文件中的两个bean:

@Bean
public FilterRegistrationBean someFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
}

public Filter someFilter() {
    return new SomeFilter();
}

以上是用Spring Boot 1.2.3测试的。