簡體   English   中英

Spring boot async:在異步方法中獲取 HttpServletRequest

[英]Spring boot async: get HttpServletRequest inside async method

我已在 Spring Boot 應用程序中啟用異步:

@Configuration
@EnableAsync
public class BackOfficeConfiguration {}

我創建了這個異步方法:

@Async
public void importDocuments() {}

importDocuments代碼只是:

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

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

RequestContextHolder.currentRequestAttributes() ,spring boot 給我這個異常:

java.lang.IllegalStateException: No thread-bound request found: 您是指實際 Web 請求之外的請求屬性,還是在原始接收線程之外處理請求? 如果您實際上是在 Web 請求中操作並且仍然收到此消息,則您的代碼可能在 DispatcherServlet/DispatcherPortlet 之外運行:在這種情況下,請使用 RequestContextListener 或 RequestContextFilter 來公開當前請求。

如何在異步方法中獲取當前的HttpServletRequest

如果您在方法上使用 @Async,則意味着該方法會拋出另一個新線程(單獨的線程)。 這意味着,它與您當前的請求無關。 (那是兩條路)。 如果你想從請求中獲取一些數據,你必須從請求中獲取你想要的數據並將其作為副本保存。 因為,完成后請求數據將被刪除。 如果您在那里傳遞了引用,則在訪問數據時會出現錯誤,例如No thread-bound request found 您必須創建一個Cloneable對象並將數據填充到該對象中並在調用 Async 方法之前獲取一個克隆,並通過傳遞該對象來調用 Async 方法。 那么您就有了該數據的副本,您可以在新線程中使用它(@Async 方法)。 如下所示的 Cloneable 類。

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

}

閱讀更多https://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM