为什么spring boot过滤器调用两次?

Nes*_*aau 4 java spring-boot

我的 Spring Boot 版本是 1.5.4,这是我的配置代码

@SpringBootApplication
@Configuration
@RestController
@ServletComponentScan
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @RequestMapping("/")
    public String home() {
        System.out.println("test");
        return "Hello World!";
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的 servlet 过滤器代码

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


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("LogFilter");
    chain.doFilter(request, response);
}

//init and destroy
Run Code Online (Sandbox Code Playgroud)

当我访问http://localhost:8080/ 时,控制台打印出来了

LogFilter
test
LogFilter <----the second time
Run Code Online (Sandbox Code Playgroud)

为什么要调用 filter 两次?Spring boot 为什么要这样做?有没有相关的文件或者来源参考?我要他打一次电话,怎么办?

更新:thx所有问题都已解决

小智 17

请检查您定义过滤器的类是 bean 还是常规类。如果它是一个 bean/组件,那么您不必在安全配置中专门注册过滤器,例如通过使用

http.addFilterBefore(new YourFilter(), BasicAuthenticationFilter.class). 
Run Code Online (Sandbox Code Playgroud)

通过如上所述额外注册一个 bean,同一个过滤器将被执行两次。

  • 谢谢,这正是我的情况。应该位于顶部,因为这是当您阻止诸如调用 URL 两次之类的事情时唯一可能的原因 (2认同)

小智 7

如果您尝试从 doFilter 方法记录请求 url,您就会明白原因。这是我创建新的 SpringBoot 项目并使用 doFilter 方法进行测试。

    @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    logger.info(request.getRequestURL().toString());
    filterChain.doFilter(servletRequest,servletResponse);
}
Run Code Online (Sandbox Code Playgroud)

嗯,这两个网址是

http://localhost:8080/index
http://localhost:8080/favicon.ico
Run Code Online (Sandbox Code Playgroud)


Adr*_*ter 2

我可以想到这种行为的两个常见原因:

  1. spring 应用程序上下文被您的应用程序加载两次
  2. 重定向正在端点上引发第二个请求