java 为什么 Spring Boot 过滤器调用两次?

bksxznpy  于 2022-12-21  发布在  Java
关注(0)|答案(4)|浏览(685)

我的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!";
    }

}

下面是我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

当我访问http://localhost:8080/时,控制台已打印完毕

LogFilter
test
LogFilter <----the second time

为什么要调用filter两次?Sping Boot 为什么要这样做?有没有相关的文档或者源代码参考?我想让他在哪里调用一次,怎么做?
更新:thx所有的问题已经解决

ftf50wuq

ftf50wuq1#

如果你尝试从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);
}

这两个网址是

http://localhost:8080/index
http://localhost:8080/favicon.ico
lfapxunr

lfapxunr2#

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

http.addFilterBefore(new YourFilter(), BasicAuthenticationFilter.class).

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

w6lpcovy

w6lpcovy3#

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

  1. Spring应用程序上下文由应用程序加载两次
    1.重定向导致端点上的第二个请求
c7rzv4ha

c7rzv4ha4#

该问题的答案在文档中:
每当由于客户端请求链末端的资源而使request/response对通过链时,容器都会调用Filter的doFilter方法。
Source

相关问题