2

I've enabled async into my spring boot application:

@Configuration
@EnableAsync
public class BackOfficeConfiguration {}

and I've created this async method:

@Async
public void importDocuments() {}

importDocuments code is just:

@Async
public void importDocuments() {
    // Do something

    // Get current request context
    ServletRequestAttributes requestAttributes = 
        (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
    HttpServletRequest request = requestAttributes.getRequest();
}

On RequestContextHolder.currentRequestAttributes(), spring boot is getting me this exception:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

How could I get current HttpServletRequest inside an async method?

Jordi
  • 20,868
  • 39
  • 149
  • 333

1 Answers1

2

if you are using @Async on a method, that means that method throws into another new thread(separated one). that means, it is not related to your current request. (those are two roads). if you want to get some data from the request, you have to get the data that you want from the request and keep it as a copy. Because, after complete the request data will be removed. if you had passed the reference there, you will get an error when accessing the data like No thread-bound request found. you have to create a Cloneable object and fill the data into that object and get a clone before calling the Async method and call the Async method by passing that object. then you have a copy of that data and you can use it inside pf your new thread (@Async method). A Cloneable class like below.

public class CloneableClass implements Cloneable {
    //
    private ServletRequestAttributes requestAttributes;
    //getters
    //setters

    @Override
    public CloneableClass  clone() {
        try {
            CloneableClass clone = (CloneableClass) super.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

}

read more on https://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html

Mafei
  • 3,063
  • 2
  • 15
  • 37