当前位置: 首页 > 知识库问答 >
问题:

注册MessageBodyReader和MessageBodyWriter实现的正确位置是哪里?

臧彭亮
2023-03-14

我已经实现了 Javax WS RS API 消息正文阅读器,用于网站 1.cmp.客户端,通用 PKI消息服务器阅读器消息正文编写器,用于组织.反弹castle.asn1.cmp.PKI消息,以便我可以通过 HTTP REST API 轻松使用 CMP 中的类型。现在,为了注册这些类型,我创建了元-INF/服务/javax.ws.rs.ext.提供程序文件,并将类名放在那里。一切正常,我可以使用API进行REST调用,除了:

>

  • IntelliJ IDEA(或我安装到其中的一个插件)抱怨说

    注册扩展应实现 javax.ws.rs.ext.提供程序

    在文件的两行上。根据我在互联网上找到的资源,我认为添加@Provider@Produces(“application/pkixcmp”)annotation就足够了。

    我注意到,更快的XML杰克逊有元INF/服务/javax.ws.rs.ext.消息正文阅读器元INF/服务/javax.ws.rs.ext.消息正文文件,这些文件似乎也注册了一个实现接口的类。

    所以我的问题是:

    >

  • IntelliJ IDEA抱怨我没有实现javax.ws.rs.ext.Providers是正确的还是错误的?

    注册MessageBodyReaderMessageBodyWriter实现的正确文件是什么?

    有什么权威文档可以启发我这方面的知识?

  • 共有1个答案

    水昊阳
    2023-03-14

    IntelliJ IDEA抱怨我没有实现javax.ws.rs.ext.Providers是正确的还是错误的?

    < code>META-INF/services中的文件是我们利用< code>ServiceLoader创建可扩展应用程序的一部分。它的工作原理是,文件名应该是契约的名称,文件的内容应该是该契约的实现列表。< code>ServiceLoader将会看到该文件并收集所有实现。因此,使用< code>ServiceLoader,我们可以

    ServiceLoader<MessageBodyReader> readersLoader
            = ServiceLoader.load(MessageBodyReader.class);
    

    根据传递给load方法的类,Java将搜索文件

    META-INF/services/javax.ws.rs.ext.MessageBodyReader
    

    并查看该文件的内容以查找它应该加载的所有实现。

    因此,根据这些信息,您可以看到IntelliJ的抱怨是正确的,因为您的读者和作者没有正确实现javax.ws.rs.ext.Providers

    我应该指出的一点是,我不认为ServiceLoader类是直接使用的,因为它要求服务实现没有arg构造函数。但这正是META服务所使用的模式。

    注册MessageBodyReaderMessageBodyWriter实现的正确文件是什么?

    META-INF/services文件的使用不是JAX-RS规范的一部分。这是一个特定于JAX-RS实现的实现细节,尽管这种模式被大量使用。您将主要看到文件在可重用库中使用,例如您提到的Jackson库1

    如果提供者将成为我们的应用程序的一部分,那么有更常见的方法来注册它。

    > < li>

    您提到的< code>@Provider批注是一个标记批注,用于检测应该注册的提供程序类。启用扫描时,运行时会扫描用< code>@Provider注释的类,然后将它们注册到应用程序中。

    当我们谈到扫描时,有几种不同的方式:类路径扫描和包扫描。在JAX-RS应用程序中,类路径扫描是通过一个用< code>@ApplicationPath注释的空< code>Application类来启用的。

    @ApplicationPath("/api/*")
    public class ApplicationConfig extends Application {}
    

    这足以使 JAX-RS 应用程序配置为2。将启用类路径扫描,这将扫描整个类路径中所有用@Path批注的类,并@Provider并注册这些类。

    包扫描是Jersey实现所特有的。我们可以这样配置应用程序

    @ApplicationPath("api")
    public class ApplicationConfig extends ResourceConfig {
        public ApplicationConfig() {
            package("the.package.to.scan");
        }
    }
    

    在这里,我们告诉Jersey扫描.package.to.scan包中的@Path@Provider类以注册应用程序。

    注册我们的提供者的另一种方法是显式注册它们。在Application子类中,您可以覆盖getClass()getSingletons()以分别将它们注册为类或对象。

    @ApplicationPath("/api/*")
    public class ApplicationConfig extends Application {
        private final Set<Class<?>> classes = new HashSet<>();
        private final Set<Object> singletons = new HashSet<>();
    
        public ApplicationConfig() {
            classes.add(MyMessageBodyReader.class);
            singletons.add(new MyMessageBodyReader());
        }
    
        @Override
        public Set<Class<?>> getClasses() {
            return this.classes;
        }
    
        @Override
        public Set<Object> getSingletons() {
            return this.singletons;
        }
    }
    

    请注意,一旦您覆盖这些方法中的任何一个并返回非空集,类路径扫描将自动禁用,您将需要手动注册所有内容。

    如果您使用的是Jersey实现,也有一些Jersey特定的方法,我们可以显式地注册资源和提供者。有关这方面的更多讨论,请参见Jersey 2中的ResourceConfig类到底是什么?。

    我可以考虑注册提供商的另一种方法是通过使用功能。我们可以使用vanillaFeature或者我们可以使用DynamicFeature

    通过< code >特性,我们向整个应用程序注册了提供者

    // We should register the feature with our application
    public class MyFeature implements Feature {
        @Override
        public boolean configure(FeatureContext context) {
             context.register(MyMessageBodyReader.class);
        }
    }
    

    使用DynamicFeature,我们可以有选择地使用特定的资源方法或资源类注册提供者。有关动态绑定的详细信息,请参阅泽西岛文档。应该注意的是,动态绑定更多地用于过滤器和拦截器(也就是一般意义上的提供者),而不是实体提供者(MessageBodyReader/Writers)。

    可能还有其他方法来注册您的提供商,但上面提到的方法是您在应用程序中看到的主要方法。

    有什么权威文档可以启发我这方面的知识?

    我不确定任何留档中有多少关于META-INF/service文件的信息。但是显式注册和类路径扫描,您可能会在JAX-RS规范或泽西留档中找到

    1 - 应该注意的是,仅仅因为文件在那里,并不意味着它将被使用。这取决于 JAX-RS 实现是否愿意使用它。例如,泽西岛不会在消息正文阅读器和作家上使用它。

    2-请参阅如何在没有web.xml的情况下将Jersey用作JAX-RS实现

     类似资料:
    • 问题内容: 我已经实现的javax WS RS API 用于和对这样我就可以在轻松的使用类型CMP过HTTP REST API。现在,要注册我创建的文件的类型并将类名放在此处。一切正常,我可以使用API​​进行REST调用,但以下情况除外: IntelliJ IDEA(或我已安装到其中的插件之一)抱怨 注册的扩展名应实现javax.ws.rs.ext.Providers 在文件的两行上。根据我在I

    • 想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。 我刚刚读到JRE是JVM的一个实现,HotSpot VM也是JVM的一个实现。哪一个 是否正确?

    • 在呈现WEB-CONTENT/WEB-INF/jsp/index.jsp时为DispatcherServlet获取类未找到异常index.jsp 以下是项目的结构。 网络。xml属于WEB内容 我在smaple项目中使用注释驱动控制器。

    • 问题内容: 我应该在Eclipse项目中的哪个位置添加文件,以便它可以按预期工作? 问题答案: 您可以将其添加到任意位置,在运行项目时,通过单击以下命令来配置类路径并添加log4j.properties文件的位置:运行->运行配置-> [类路径选项卡]->单击用户条目- >高级->选择添加文件夹->选择log4j.properties文件的位置 然后->确定->运行 它应该被加载

    • 我正在使用https://pub.dev/packages/firebase_messagingv6。0.16和颤振v1。17.5 我正在尝试调用myBackgroundMessageHandler中的一个插件,它的代码是AppAvailability。启动应用程序('com.companyname.appname') 但我得到以下错误 插件在应用程序范围内没有任何问题。这是发生在我尝试的每一个插

    • 使用Fork-Join框架的资源,创建一个同步多线程系统,从三个文本文件中形成一个最大长度的单词集合。不要使用中间集合来读取文本。在本例中,工作由存储在MaxLengthWord类的arr字段中的数组表示。createSubtasks()方法递归地将任务分成更小的工作部分,直到每个工作部分都小于阈值。