2012-11-12 79 views
1

我在過濾器中使用RequestContextHolder來記錄一段數據,並希望在稍後通過POJO(通過Spring連線)訪問它。我收到了一個異常,表明我在這裏做錯了什麼,希望能對此有所指導。IllegalStateException當使用Spring RequestContextHolder時

過濾代碼(在的doFilter()方法,其記錄證實了它被稱爲):

RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); 
if (attrs == null) 
{ 
    logger.info("Creating new ServletRequestAttributes"); 
    attrs = new ServletRequestAttributes(servletRequest); 
} 

attrs.setAttribute("my_attr", "hello there!", RequestAttributes.SCOPE_REQUEST); 

RequestContextHolder.setRequestAttributes(attrs); 

POJO代碼:

RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); 
if (attrs != null && attrs.getAttribute("my_attr", RequestAttributes.SCOPE_REQUEST) != null) 
{ 
    String myAttr = (String) attrs.getAttribute("my_attr", RequestAttributes.SCOPE_REQUEST); 
    logger.debug("Got it: ", myAttr); 
} 

我看到這個異常從Tomcat來,雖然:

java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade 
    at org.apache.catalina.connector.RequestFacade.getAttribute(RequestFacade.java:259) 
    at org.springframework.web.context.request.ServletRequestAttributes.getAttribute(ServletRequestAttributes.java:98) 
    at com.mycompany.MyClass(MyClass.java:50) 

我不知道是否有「在過濾器中設置數據「,並通過請求的實際工作」獲取數據「可能在這裏起作用,但不確定如何最好地適應這種情況,甚至是相關的?

回答

1

這個錯誤很可能是由於你讓Spring維護一個不再有效的請求對象的線程本地句柄。細節可能並不重要,因爲要採取不同的方法。

下列其中一個將負責自動設置和清除線程本地狀態:DispatcherServlet,RequestContextListenerRequestContextFilter。你需要弄清楚哪一個最適合你的應用使用Spring。你的過濾器和POJO代碼不需要直接使用像RequestContextHolder這樣的類。什麼應該發生的是,聲明該屬性的代理,請求範圍豆你要訪問:

<bean id="myAttr" scope="request"> 
    <aop:scoped-proxy/> 
</bean> 

然後,它在請求範圍豆依賴一起申報您的POJO豆:

<bean id="myPojo"> 
    <property name="myAttr" ref="myAttr"/> 
</bean> 

參見:Request, session, and global session scopes

應該採取的所有細節關懷......

+0

聽起來PR omising,我會給它一個去,並回報 – Brian

+0

嘿;沒有找到實際爲我工作的配置的工作組合。我懷疑你的回答是非常正確的,但我現在只想看看替代方案,不想再投入更多時間。謝謝! – Brian

相關問題