我已经实现了 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
是正确的还是错误的?
注册MessageBodyReader
和MessageBodyWriter
实现的正确文件是什么?
有什么权威文档可以启发我这方面的知识?
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服务所使用的模式。
注册MessageBodyReader
和MessageBodyWriter
实现的正确文件是什么?
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()方法递归地将任务分成更小的工作部分,直到每个工作部分都小于阈值。