6

我正在编写自定义 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;

原因appnull,由于ClassCastException在上下文注入期间,所以声明的类型无关紧要。

这是泽西岛的错误还是我的误解?

更新:我检查了 RESTEasy 3.0 下的行为。注入的对象是 my WebApp,没有任何包装。我会称之为泽西岛的一个错误。

4

3 回答 3

2

这似乎不是一个错误。根据 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);
            }
        });
    }
}
于 2013-11-15T13:25:16.280 回答
1

我也遇到过使用 Jersey 2.4.1 的情况。

FWIW:我同意根据规范第 8.2.1 段,这似乎是一个错误。声明“应用程序提供的应用程序子类的实例”似乎非常清楚。

我有一个不涉及 glassfish.hk2 但仍将 Jersey 特定代码集中在应用程序派生类中的替代解决方法。

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);
    }
}

希望这是有用的。

于 2014-01-09T13:28:44.213 回答
0

这似乎在以后的版本 og Jersey 中得到修复。同样的方法至少适用于我的 Jersey 2.16。我注入的 Application 对象是正确的子类,没有任何包装。

编辑:或者也许版本是无关紧要的。请参阅对此答案的评论。

于 2015-04-15T09:51:52.613 回答