1

フィルタで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)

フィルタに「データを設定」し、リクエストの実際の作業を介して「データを取得」することがここで機能するのではないかと思いますが、それが適切であるとしても、それに対応する最善の方法がわかりません。

4

1 に答える 1

1

このエラーは、Springに無効になったリクエストオブジェクトへのスレッドローカルハンドルを維持させていることが原因である可能性があります。別のアプローチが必要なので、詳細はおそらくそれほど重要ではありません。

次のいずれかが、スレッドローカル状態を適切に自動的に設定およびクリアします:DispatcherServlet、、RequestContextListenerまたはRequestContextFilter。Springがアプリでどのように使用されるかについて、どれが最も理にかなっているのかを理解する必要があります。RequestContextHolderフィルタとPOJOコードは、直接のようにクラスを使用する必要はありません。何が起こるかというと、アクセスしたい属性に対して、プロキシされたリクエストスコープのBeanを宣言することです。

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

次に、POJOのBeanを、リクエストスコープのBeanへの依存関係とともに宣言します。

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

参照:リクエスト、セッション、およびグローバルセッションスコープ

春はすべての詳細を処理する必要があります...

于 2012-11-12T21:21:51.450 に答える