我看过许多以
之类的东西开头的泽西教程@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
packages("com.abc.jersey.services");
}
}
没有解释ResourceConfig
类究竟是什么。那么我在哪里可以找到它的文档,用法等?谷歌搜索“泽西资源配置”不会产生任何官方文档。
我对这个课程及其用法的一些问题是:
ResourceConfig
的子类中可以做些什么? ResourceConfig
的子类以便可以找到它或者是否由Jersey自动检测到它? ResourceConfig
的子类?ResourceConfig
的目的是否与web.xml
文件相同?如果是这样的话,如果我在我的项目中同时出现这种情其中一个优先于另一个吗?答案 0 :(得分:109)
标准JAX-RS使用Application
作为其配置类。 ResourceConfig
延伸 Application
。
有三种主要的不同方式(在servlet容器中)配置Jersey(JAX-RS):
Application/ResourceConfig
类Application/ResourceConfig
类注明@ApplicationPath
。可以使用标准的JAX-RS方式配置应用程序,但以下内容特定于Jersey
<web-app>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.mypackage.to.scan</param-value>
</init-param>
</servlet>
...
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
...
</web-app>
由于Jersey在servlet容器中运行,因此Jersey应用程序作为servlet运行是正确的。处理传入请求的Jersey Servlet是ServletContainer
。所以在这里我们将其声明为<servlet-class>
。我们还配置<init-param>
告诉Jersey哪些软件包要扫描我们的@Path
和@Provider
类,以便它们注册它们。
在幕后,Jersey实际上会创建一个ResourceConfig
实例,就像它用来配置应用程序一样。然后它将注册它通过包扫描发现的所有类。
Application/ResourceConfig
如果我们想以编程方式使用Application
或ResourceConfig
子类配置我们的应用程序,我们可以对上面的web.xml进行一次更改。我们使用init-param来声明我们的Application/ResourceConfig
子类,而不是设置init-param来扫描包。
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.JerseyApplication</param-value>
</init-param>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</servlet>
package com.example;
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
packages("com.abc.jersey.services");
}
}
在这里,我们使用init-param
子类的完全限定名称配置javax.ws.rs.Application
ResourceConfig
。而不是使用告诉Jersey要扫描哪个包的init-param
,我们只使用packages()
的便捷方法ResourceConfig
。
我们还可以使用方法register()
和property()
来注册资源和提供程序,以及配置Jersey属性。使用property()
方法,可以使用init-param
方法配置任何可以配置为property()
的方法。例如,我们可以执行
packages()
public JerseyApplication() {
property("jersey.config.server.provider.packages",
"com.mypackage.to.scan");
}
Application/ResourceConfig
如果没有web.xml,Jersey需要一种方法来提供servlet映射。我们使用@ApplicationPath
注释执行此操作。
// 'services', '/services', or '/services/*'
// is all the same. Jersey will change it to be '/services/*'
@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
packages("com.abc.jersey.services");
}
}
这里有@ApplicationPath
,就像我们在web.xml中配置servlet映射一样
<servlet-mapping>
<servlet-name>JerseyApplication</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
当仅使用Java代码进行配置时,Jersey需要有一些方法来发现我们的配置类。这是通过使用ServletContanerInitializer
来完成的。这是Servlet 3.0规范中引入的内容,因此我们不能仅使用&#34; Java&#34;早期servlet容器中的配置。
基本上发生的事情是初始化程序的实现者可以告诉servlet容器要查找的类,而servlet容器会将这些类传递给初始化程序onStartup()
方法。在泽西岛初始化程序的实现中,Jersey将其配置为查找Application
使用@ApplicationPath
注释的类和类。有关详细说明,请参阅this post。因此,当servlet容器启动应用程序时,Jersey的初始化程序将通过我们的Application/ResourceConfig
类。
看看javadoc。它主要只是注册课程。你不需要做太多其他事情。您将使用的主要方法是register()
,packages()
和property()
方法。 register()
方法允许您手动手动注册资源和提供程序的类和实例。前面讨论过的packages()
方法列出了您希望Jersey扫描@Path
和@Provider
类的软件包,并为您注册。 property()
方法允许您设置一些configurable properties 1 。
ResourceConfig
只是一个便利类。请记住,它扩展了Application
,因此我们甚至可以使用标准Application
类
@ApplicationPath("/services")
public class JerseyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<>();
classes.add(MyResource.class);
return classes;
}
@Override
public Set<Object> getSingletons() {
final Set<Object> singletons = new HashSet<>();
singletons.add(new MyProvider());
return singletons;
}
@Override
public Map<String, Object> getProperties() {
final Map<String, Object> properties = new HashMap<>();
properties.put("jersey.config.server.provider.packages",
"com.mypackage.to.scan");
return properties;
}
}
使用ResourceConfig
,我们只会
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
register(MyResource.class);
register(new MyProvider());
packages("com.mypackages.to.scan");
}
}
除了更方便之外,还有一些帮助泽西配置应用程序的东西。
以上所有示例都假设您在已安装的服务器环境中运行,例如Tomcat的。但您也可以在SE环境中运行应用程序,在该环境中运行嵌入式服务器并从main
方法启动应用程序。在搜索信息时,您有时会看到这些示例,因此我想展示它的外观,以便当您每次遇到此问题时,您都不会感到惊讶,并且知道它与您的设置有何不同。
所以有时你会看到像
这样的例子ResourceConfig config = new ResourceConfig();
config.packages("com.my.package");
config.register(SomeFeature.class);
config.property(SOME_PROP, someValue);
这里最有可能发生的例子是使用嵌入式服务器,如Grizzly。启动服务器的其余代码可能类似于
public static void main(String[] args) {
ResourceConfig config = new ResourceConfig();
config.packages("com.my.package");
config.register(SomeFeature.class);
config.property(SOME_PROP, someValue);
String baseUri = "http://localhost:8080/api/";
HttpServer server = GrizzlyHttpServerFactory
.createHttpServer(URI.create(baseUri), config);
server.start();
}
因此,在此示例中,启动了一个独立服务器,ResourceConfig
用于配置Jersey。这里和之前的示例的不同之处在于,在此示例中,我们不是扩展ResourceConfig
,而是仅实例化它。如果我们这样做,那就不会有任何不同了。
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("com.my.package");
register(SomeFeature.class);
property(SOME_PROP, someValue);
}
}
HttpServer server = GrizzlyHttpServerFactory
.createHttpServer(URI.create(baseUri), new JerseyConfig());
假设您正在阅读一些教程,并且它显示了一个独立应用程序的配置,它们实例化了ResourceConfig
,但是您正在servlet容器中运行您的应用程序并且一直在使用您之前的配置正在扩展ResourceConfig
。那么现在你知道区别是什么以及你需要做出哪些改变。我看到人们做了一些非常奇怪的事情,因为他们并不了解这种差异。例如,我看到有人在资源类中实例化ResourceConfig
。所以这就是为什么我添加了这个额外的小块;所以你不要犯同样的错误。
<子> 1。有许多不同的可配置属性。 ServerProperties
的链接只是一些常规属性。还有与特定功能相关的不同属性。文档应在与该功能相关的文档部分中提及这些属性。有关所有可配置属性的完整列表,您可以查看所有Jersey constants并查找字符串值以jersey.config
开头的那些属性。如果您使用的是web.xml,那么您将使用字符串值作为init-param
param-name
。如果您使用的是Java配置(ResourceConfig
),那么您可以调用property(ServerProperties.SOME_CONF, value)