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

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

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


当前回答

这是一个建议而不是答案,但如果你在你的web应用程序中使用Spring MVC,最好使用Spring HandlerInterceptor而不是Filter。

它可以做同样的工作,但是

可以使用ModelAndView吗 它的方法可以在请求处理之前和之后调用,或者在请求完成之后调用。 它很容易测试

1. 实现HandlerInterceptor接口,并向类中添加@Component注释

@Component
public class SecurityInterceptor implements HandlerInterceptor {

    private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.getSession(true);
        if(isLoggedIn(request))
            return true;

        response.getWriter().write("{\"loggedIn\":false}");
        return false;
    }

    private boolean isLoggedIn(HttpServletRequest request) {
        try {
            UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
            return userSession != null && userSession.isLoggedIn();
        } catch(IllegalStateException ex) {
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

2. 配置拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private HandlerInterceptor securityInterceptor;

    @Autowired
    public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
        this.securityInterceptor = securityInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
    }

}

其他回答

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

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

然后使用@ServletComponentScan注册。

众所周知,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 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 {}

}

下面是我的自定义Filter类的一个例子:

package com.dawson.controller.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Component
public class DawsonApiFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json");
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
            return;
        }
        chain.doFilter(request, response);
    }
}

我将它添加到Spring Boot配置中,如下所示:

package com.dawson.configuration;

import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@SpringBootApplication
public class ApplicationConfiguration {
    @Bean
    public FilterRegistrationBean dawsonApiFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new DawsonApiFilter());

        // In case you want the filter to apply to specific URL patterns only
        registration.addUrlPatterns("/dawson/*");
        return registration;
    }
}

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