Spring Loads a filter twice for queries returning a CompletionStage

I had a problem when my filter was run twice when the methods returned CompletionStage. From the documentation for RequestMapping( here ), this is a supported return value.

A CompletionStage (implemented, for example, CompletableFuture), which the application uses to get the return value in a separate stream of its choice, as an alternative to returning the called one.

Since the project was quite complex with lots of parallel code, I created a new simple spring-boot project. This is (only) the controller in it:

@Controller
public class BaseController {
    @RequestMapping("/hello")
    @ResponseBody
    public CompletionStage<String> world() {
        return CompletableFuture.supplyAsync(() -> "Hello World");
    }
}

And filter:

@WebFilter
@Component
public class GenericLoggingFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        System.out.println(httpServletRequest.getMethod() + " " +
                           httpServletRequest.getRequestURI());

        chain.doFilter(request, response);
    }
}

When I make a call curl http://localhost:8080/hello, it prints twice GET /helloto the console. When I change the controller method to return String:

@RequestMapping("/hello")
@ResponseBody
public String world() {
    return "Hello World";
}

. , Callable, concurrency (, spring Async).

, spring -, , , :

@RequestMapping("/hello")
@ResponseBody
public CompletionStage<String> world() {
    return CompletableFuture.supplyAsync(() -> {
        System.out.println(RequestContextHolder.currentRequestAttributes());
        return "Hello World";
    });
}

: IllegalStateException: No thread-bound request found...

, :

@RequestMapping("/hello")
@ResponseBody
public Callable<String> world() {
    return () -> {
        System.out.println(RequestContextHolder.currentRequestAttributes());
        return "Hello World";
    };
}

, .

  • , Callable CompletionStage - , .
  • , ? , CompletionStage, .
  • , ?
+4
1

, GenericFilterBean OncePerRequestFilter.

+2

Source: https://habr.com/ru/post/1671126/


All Articles