Jersey 2.26+:将 HK2 的工厂转换为供应商后未调用 configure()

Posted

技术标签:

【中文标题】Jersey 2.26+:将 HK2 的工厂转换为供应商后未调用 configure()【英文标题】:Jersey 2.26+: configure() not called after converting HK2's Factory to Supplier 【发布时间】:2021-07-17 13:05:42 【问题描述】:

为了简化我们的网络服务,我想在 2.34 版本中使用 Jersey 框架引入一个自定义的 MyObj 类,并希望通过 @Context 注入创建的实例注释。

我有两个问题:

    假设一个 web 服务方法 @GET test(@Context MyObj obj),我如何控制 when MyObj 的实例在关于现有 servlet 请求过滤器的执行?

    要创建 MyObj 的实例,我已经有了一个基于 HK2 的 Factory 的工作示例(见下文)。由于我观察到我的工厂类被实例化了两次,并且 Jersey 2.26+ 建议使用基于 Supplier 的新方法,因此我尝试转换我的示例。不幸的是,在提供的 Binder 实现 Supplier 类中不会调用 configure(),因此不会创建任何对象。我怎样才能得到这个工作? (顺便说一句,在这两种情况下,BinderBinderHK 都是通过 jersey.config.server.provider.classnames 在我的 web 中注册的.xml。)

感谢您的帮助。

工作中的 HK2 工厂示例:

public class MyObjHK 

import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class BinderHK
extends AbstractBinder 
    @Override protected void configure() 
        bindFactory(MyObjFactoryHK.class).to(MyObjHK.class).in(RequestScoped.class);
    


import org.glassfish.hk2.api.Factory;
public class MyObjFactoryHK
implements Factory<MyObjHK> 
    @Override public MyObjHK provide() return new MyObjHK(); // ok
    @Override public void dispose(MyObjHK instance) ;


public class API_HK2 
    @GET
    public static Response myobjhk(@Context MyObjHK obj) 
        System.out.println("called hk, obj="+obj); // ok
        return Response.ok().build();
    

不工作的供应商示例:

public class MyObj 

import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class Binder
extends AbstractBinder 
    @Override protected void configure()  // not called ???
        bindFactory(MyObjFactory.class).to(MyObj.class).in(RequestScoped.class);
    


import java.util.function.Supplier;
public class MyObjFactory
implements Supplier<MyObj>  
    @Override public MyObj get() return new MyObj();


public class API 
    @GET
    public static Response myobj(@Context MyObj obj) 
        System.out.println("called, obj="+obj); // null ???
        return Response.ok().build();
    

【问题讨论】:

【参考方案1】:

活页夹不是可以使用jersey.config..classnames init-param 注册的东西。您需要使用 ResourceConfigFeature 注册它(并使用 init-param 注册功能)

@Provider
public class MyFeature implements Feature 
    @Override
    pubic boolean configure(FeatureContext ctx) 
        ctx.register(new MyBinder());
        return true;
    

【讨论】:

谢谢,但 MyFeature/Binder 方法对我也不起作用(我尝试使用 init-param jersey.config.server.provider.classnames 以及 jersey.config.server.provider 进行注册。与@Provider 一起打包)。此外,与您的说法相反,即使不使用功能,注册 BinderHK extends AbstractBinder (请参阅下面的工作示例)也可以工作。欢迎提供更多提示。 在eclipse-ee4j.github.io/jersey.github.io/documentation/latest/…,第24.1章的例子中,直接注册了一个AbstractBinder的实现。它与解释相匹配:“虽然各个注入绑定实现会有所不同并取决于您的用例,但要在 Jersey 中启用您的自定义注入扩展,您必须在您的应用程序 ResourceConfig 中注册您的自定义 HK2 Binder 实现!”。现在,我想知道 web.xml 是否还不够,但我真的必须明确使用 ResourceConfig 实例(我还没有测试过)? 该文档已多年未更新。特别是关于HK2。如您所见,它仍然使用 HK2,尽管这不再是推荐的用法。除非您特别需要 HK2 功能,否则您所有的注入导入都应该来自 jersey.internal.inject 包。 好的,在设置一个完整的示例时,我显然发现了问题。我不小心用 @Provider 注释了 AbstractBinderFeature 类。删除 AbstractBinder 类中的注释并将其仅保留在 Feature 类中(根据您的回答),问题就消失了。感谢您的支持。我有最后一个问题:我仍然必须保持 org.glassfish.jersey.inject - jersey-hk2 依赖项(在 pom.xml 中的 2.34 版本中)以保持工作正常吗? Yes it's still required.

以上是关于Jersey 2.26+:将 HK2 的工厂转换为供应商后未调用 configure()的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Jersey

java.lang.NoSuchMethodError: org.glassfish.hk2.api.ServiceLocatorFactory.creat - 泽西岛

Jersey 2.0 的依赖注入

将使用 jersey 1.x 的 java 代码转换为 jersey 2.x

Spring Boot + Jersey发生FileNotFoundException (No such file or directory)

如何使用 Jersey 将嵌套列表编组为 JSON?我得到一个空数组或一个包含数组的单元素字典数组