1

I'm using a Servlet 3 controller in a Spring Boot application. This controller calls services that, in the end, make 3 HTTP requests.

@GetMapping("/nbasync/c/**")
public CompletableFuture<String> nonBlockingAsyncCall() throws Exception {
    CompletableFuture<String> result = service.call());

    CompletableFuture<Void> result2 = service2.call();
    CompletableFuture<Void> result3 = service3.call();

    return result
            .thenCombine(result2, this::keepFirst)
            .thenCombine(result3, this::keepFirst);
}

Each of this outgoing calls are made using a RestTemplate and are intercepted by a ClientHttpRequestInterceptor. In this ClientHttpRequestInterceptor, I need a (proxied) request scoped bean (cf: How to enable request scope in async task executor with a Runnable).

This works just fine if I wait for the the result :

    CompletableFuture.allOf(result, result2, result3).join();
    return result.get();

In the non blocking method, it crashes with the following exception :

java.util.concurrent.CompletionException: 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.requestCookieHelper': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is 
java.lang.IllegalStateException: Cannot ask for request attribute - request is not active anymore!

See complete log : https://gist.github.com/Skeebl/d0b19ebb9ab4d0d2a917203e4bd6fad5

It appears that each time a thread lets go of the process, AbstractRequestAttributes.requestCompleted() is called (twice). This methods sets this.requestActive = false;. While requestActive is false, you can't access the request scoped beans.

The interceptor and request scoped bean simplify the methods signatures. Is there a way to keep theses while working with async requests ?

Skeebl
  • 122
  • 1
  • 9
  • hey, do you know how can we retain the request object after the async has been triggered. I am losing the request object as soon as the request is completed but async is still going on. I could retain the requestattribute using RequestAttributeHolder but the request inside the attribute is losing all the properties such as URI, Headers, Attributes which are related to request. Any option to retain, either by creating a new copy and keep or clone like that. – Shafs Jan Oct 06 '17 at 14:11

0 Answers0