2011-02-18 60 views
5

我正在開發一個使用Struts 2和Spring 3後端的web應用程序。我使用Spring aop:代理bean來處理會話bean,而不是Struts 2 SessionAware接口。一切正常,直到我有一個在Struts ExecAndWait攔截器下運行的Action。因爲這個攔截器實際上在一個單獨的線程下運行我的動作,當我試圖訪問我的代理會話bean時,我得到一個BeanCreationException/IllegalStateException異常。在這種情況下,我能否獲得會話bean的另一種「春天方式」?訪問Spring Session作用域代理bean

Regards

+0

當然,當您的子線程需要訪問該bean時,會話可能已被用戶銷燬。可能需要重新審視您的範圍。 – 2013-10-29 21:24:56

回答

0

您可以使用Spring實現您自己的ExecAndWait攔截器。您也可以將此操作的管理/創建委派給Spring。後面的細節在S2彈簧插件文檔中。

3

Execute and Wait Interceptor文檔

重要:由於動作將是在一個單獨的線程中運行,則無法使用ActionContext中,因爲它是一個ThreadLocal。這意味着如果您需要訪問會話數據,則需要實現SessionAware而不是調用ActionContext.getSession()。

會話scoped-beans的問題在於它們依賴於由RequestContextListenerRequestContextFilter設置的線程本地屬性。但後者允許你設置非常有趣的threadContextInheritable標誌......

如果你的ExecAndWait攔截器爲它所服務的每個請求創建一個新的線程,可繼承的線程本地應該將會話作用域的bean傳播給子線程。但是,如果Struts使用線程池(更有可能,您沒有使用Struts2很長時間)來處理這些請求,這將會產生非常意想不到的危險結果。你可以嘗試這個標誌,也許它會做到這一點。

0

您可以使用​​(Holder類以線程綁定的RequestAttributes對象的形式公開Web請求),以使會話作用域的代理bean可用於子線程。

定義自定義ExecuteAndWait攔截並在doIntercept方法使用下面的靜態方法從RequestContextHolder

公共靜態無效setRequestAttributes(RequestAttributes屬性,布爾可繼承

綁定給定RequestAttributes到當前線。

參數: 屬性 - 在RequestAttributes暴露,或空重置線程綁定的語境 可繼承 - 是否暴露RequestAttributes爲可繼承的子線程(使用的InheritableThreadLocal)

樣品代碼

public class CustomExecuteAndWaitInterceptor extends ExecuteAndWaitInterceptor { 

    @Override 
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception { 
     RequestAttributes requestAtteiAttributes = RequestContextHolder.getRequestAttributes(); //Return the RequestAttributes currently bound to the thread. 
     RequestContextHolder.setRequestAttributes(requestAtteiAttributes, true); 
     //do something else if you want .. 
     return super.doIntercept(actionInvocation); 

    } 
}