我正在编写自定义JAX-RS 2.0应用程序(在Jersey 2.3.1下),它包含一些数据供所有资源使用。
public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
public WebApp() {
packages("my.resources.package");
}
}
(我也可以使用API的javax.ws.rs.core.Application
,描述的结果是相同的)
然后我将对象注入资源
@Path("test")
public class Test {
@Context
Application app;
@GET
@Path("test")
public String test() {
return "Application class: " + app.getClass();
}
}
然而,通话的结果是
Application class: class org.glassfish.jersey.server.ResourceConfig$WrappingResourceConfig
让我使用了一些丑陋的技巧,比如
if (app instanceof WebApp) {
return (WebApp) app;
} else if (app instanceof ResourceConfig) {
return (WebApp) ((ResourceConfig) app).getApplication();
}
我对JAX-RS 2.0规范9.2.1的理解:
可以使用
Application
注释将应用程序提供的@Context
子类的实例注入到类字段或方法参数中。访问Application
子类实例允许将配置信息集中在该类中。请注意,这不能注入Application
子类本身,因为这会产生循环依赖。
是应用程序提供的Application
子类是我的WebApp
,而不是JAX-RS特定于实现的包装器。
另外,更改此片段
@Context
Application app;
到这个
@Context
WebApp app;
导致app
为null
,因为在上下文注入期间ClassCastException
,因此声明的类型无关紧要。
这是泽西岛的一个错误还是我的误解?
更新:我检查了RESTEasy 3.0下的行为。注入的对象是我的WebApp
,没有任何包装器。我把它称为泽西岛的一个错误。
答案 0 :(得分:1)
这似乎不是一个错误。根据JAX-RS 2.0规范,您可以将Application
注入资源类(例如),但它没有说明直接注入Application
的自定义扩展。不确定您的用例是什么,但您可以注册自定义HK2 binder,以便您直接将WebApp
注入资源:
public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
public WebApp() {
packages("my.resources.package");
register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {
@Override
protected void configure() {
bind(WebApp.this);
}
});
}
}
答案 1 :(得分:1)
我也使用Jersey 2.4.1遇到过这个。
FWIW:根据规范8.2.1,我同意这似乎是一个错误。语句“应用程序提供的应用程序子类的实例”似乎非常清楚。
我有一个替代解决方法,不涉及glassfish.hk2,但仍然将特定于Jersey的代码集中在Application派生类中。
public class MyApp extends ResourceConfig {
...
static MyApp getInstance( Application application) {
try {
// for a conformant implementation
return (MyApp) application;
} catch (ClassCastException e) {
// Jersey 2.4.1 workaround
ResourceConfig rc = (ResourceConfig) application;
return (MyApp) rc.getApplication();
}
}
...
}
public class MyResource {
...
@Context Application application;
...
SomeMethod() {
... MyApp.getInstance( application);
}
}
希望这很有用。
答案 2 :(得分:0)
这似乎在以后的版本og Jersey中修复。同样的方法至少适用于泽西岛2.16。我注入的Application对象是正确的子类,没有任何包装。
编辑:或许毕竟版本无关紧要。请参阅此答案的评论。