9

my spring boot version is 1.5.4,here is my config code

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

}

here is my servlet filter code

@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

When i visit http://localhost:8080/ console is out print

LogFilter
test
LogFilter <----the second time

why call filter twice?Spring boot Why do this? Is there a relevant document or source reference?where I want him to call once, how can i do it?

update: thx all the problem has been solved

Nestle Caau
  • 91
  • 1
  • 1
  • 5
  • I suggest using loggers instead of System.out.prinln :) Try accessing with https - would it still be the same? Maybe your tomcat forces https and rewrites the request? – xenteros Jun 27 '17 at 08:51
  • 2
    If your problem is being solved, mark the answer as a solution or post an answer yourself. – Matthias Jun 27 '17 at 09:35
  • 1
    If you want your filter to only be called once per request, extend `OncePerRequestFilter` instead of `Filter`. – Jaime Menendez Apr 08 '22 at 00:33

4 Answers4

16

Please check if the class where in you had defined your filter was a bean or a regular class. In case it is a bean/component then you do not have to specifically register the filter in your security configuration for eg by using

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

By registering a bean additionally as mentioned, the same filter will get executed twice.

wrathtoliar
  • 261
  • 3
  • 4
  • 2
    thank you, that was exactly my case. Should be on the top as this is the only possible reason when you're curtain on things like calling URL twice – Artem Ptushkin Nov 15 '21 at 10:45
  • Seem like it works for me. Before I added the filter with the injected bean. Then I change to regular class like your example. But i'm curious why it called twice if I use the injected bean. Do you know the reason behind? – K9.dev Apr 26 '22 at 04:48
12

If you try to log the request url from doFilter method, you'll see why. Here is I create new SpringBoot project and test with doFilter method.

    @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);
}

Well, the two urls are

http://localhost:8080/index
http://localhost:8080/favicon.ico
Yongzhao Zhang
  • 121
  • 1
  • 2
2

I can think of two common reasons for this behavior:

  1. the spring application context is loaded twice by your application
  2. A redirect is causing a second request on the endpoint
Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60
2

Answer to the question is in documentation:

The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.

Source

Adrian
  • 2,984
  • 15
  • 27