簡體   English   中英

使用Spring RequestContextHolder時發生IllegalStateException

[英]IllegalStateException when using Spring RequestContextHolder

我在過濾器中使用RequestContextHolder記錄一條數據,並希望稍后在POJO(通過Spring進行連接)中訪問它。 我遇到一個異常,這表明我在這里做錯了,不勝感激。

過濾器代碼(在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)

我確實想知道是否可以在過濾器中使用“設置數據”和通過請求的實際工作來“獲取數據”,但是不確定是否最好地容納它,即使它是相關的?

該錯誤很可能是由於您使Spring維護了不再有效的請求對象的線程本地句柄而導致的。 由於順序不同,因此細節可能無關緊要。

以下操作之一將自動正確設置和清除線程本地狀態: DispatcherServletRequestContextListenerRequestContextFilter 您需要找出最適合將Spring與您的應用程序一起使用的方式。 您的過濾器和POJO代碼不需要直接使用諸如RequestContextHolder之類的類。 應該發生的是,您為要訪問的屬性聲明了一個代理的,請求范圍的Bean:

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

然后,為您的POJO聲明bean及其對請求范圍bean的依賴:

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

請參閱: 請求,會話和全局會話范圍

春天應該照顧所有細節...

暫無
暫無

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

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