jose 1.13とtomcat 6で動作するspring 3.1.1を使用して休憩サービスを作成しました。 Tomcatでは認証を行う領域を使用しています。 私のアプリケーションでは現在のユーザーが必要ですが、すべてのリソースのjerseyからSecurityContextにアクセスしたくありません。私は、現在のユーザを含む残りのリソースにリクエストスコープのApplicationConfigオブジェクトを注入したいと思います。後でこのクラスを拡張して、より多くのリクエストレベルのコンフィグレーションパラメータを含めることができます。これは私にとって素晴らしい抽象的なようです。ContainerRequestFilterでSpringリクエストスコープBeanを設定する
@Component
@Scope(value = "request")
public class ApplicationConfig
{
private String userCode;
public String getUserCode()
{
return this.userCode;
}
public void setUserCode(String userCode)
{
this.userCode = userCode;
}
}
構成にアクセスできるようにApplicationConfigManagerを作成しました。
@Component
public class ApplicationConfigManager
{
@Autowired
public ApplicationConfig applicationConfig;
public ApplicationConfig getApplicationConfig()
{
return this.applicationConfig;
}
}
アプリケーションの設定マネージャはシングルトン(デフォルト)として定義されているが、ApplicationConfigはしたがって@Scopeアノテーション、要求範囲であるべきです。
私は(ジャージー)ContainerRequestFilterを使用して、アプリケーション設定オブジェクトでユーザーを設定しています。
@Component
@Provider
public class ApplicationConfigFilter implements ResourceFilter, ContainerRequestFilter
{
@Autowired
private ApplicationConfigManager applicationConfigManager;
@Override
public ContainerRequest filter(ContainerRequest request)
{
this.applicationConfigManager.getApplicationConfig().setUserCode(
request.getSecurityContext().getUserPrincipal().getName()
);
return request;
}
@Override
public ContainerRequestFilter getRequestFilter()
{
return this;
}
@Override
public ContainerResponseFilter getResponseFilter()
{
return null;
}
}
私はまた、これらのリスナーは、春のブートストラップに追加私はweb.xmlの
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mypackage</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.mypackage.ResourceFilterFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
にこれを設定することで、この工場を起動し、私はResourceFilterFactory
@Component
@Provider
public class ResourceFilterFactory extends RolesAllowedResourceFilterFactory
{
@Autowired
private ApplicationConfigFilter applicationConfigFilter;
@Override
public List<ResourceFilter> create(AbstractMethod am)
{
// get filters from RolesAllowedResourceFilterFactory Factory!
List<ResourceFilter> rolesFilters = super.create(am);
if (null == rolesFilters) {
rolesFilters = new ArrayList<ResourceFilter>();
}
// Convert into mutable List, so as to add more filters that we need
// (RolesAllowedResourceFilterFactory generates immutable list of filters)
List<ResourceFilter> filters = new ArrayList<ResourceFilter>(rolesFilters);
filters.add(this.applicationConfigFilter);
return filters;
}
}
を作成し、このフィルタを登録するにはコンテキストを有効にして要求スコープを有効にする
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
これは私が
<context:annotation-config/>
<context:component-scan base-package="com.mypackage" />
<bean id="applicationConfig" class="com.mypackage.ApplicationConfig" scope="request"/>
そして今、私の(私は春が自動的にそれを見つけるでしょう、これは必要すらないと思います)スキャン機能の作業を取得するとaplicationのconfigオブジェクトを定義するために自分のアプリケーションのコンテキストに入れものです問題。私がアプリケーションを起動すると、Springはブートストラップされ、ApplicationConfigオブジェクトをApplicationConfigFilterに注入されたApplicationConfigManagerに注入します。
この時点では、例外がスローされます:
.
.
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually o
perating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:40) ~[spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:328) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
... 57 common frames omitted
この例外はかなり明確であり、私はそれは要求が全く要求がまだ送信されなかったためにApplicationConfigを注入することができないスコープの意味だと思います。
私はApplicationConfigオブジェクトをインスタンス化する必要があります。要求が送信されたときだけで、アプリケーションの起動時ではありません。私は解決策を探して、リクエストスコープのBeanをシングルトンBeanに注入することはあまり論理的ではないことを発見しました。とにかく私はいつも同じオブジェクトを得るでしょう。解決策は、私は私のすべての要求のための新しいApplicationConfigオブジェクトを与える必要があります。この
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
これにApplicationConfigクラスに@Scopeアノテーションを変更して、プロキシを使用することです。
アプリケーションは今すぐ起動します(ApplicationConfigをインスタンス化しているようには見えません)が、私のレストサービスにリクエストを送信すると、デバッグを使用して、同じApplicationConfigオブジェクトの代わりに、リクエスト。
どうしたのですか?