泽西岛2中的ResourceConfig类到底是什么? [英] What exactly is the ResourceConfig class in Jersey 2?

查看:1450
本文介绍了泽西岛2中的ResourceConfig类到底是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过很多泽西岛的教程,都是以类似的东西开头的

I have seen a lot of Jersey tutorials that starts with something like

@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        packages("com.abc.jersey.services");
    }
}

没有解释ResourceConfig类的确切含义.那么在哪里可以找到其文档,用法等?谷歌搜索"jersey resourceconfig"不会产生任何官方文档.

without explaining what exactly the ResourceConfig class is. So where can I find its documentation, usage, etc.? Googling for "jersey resourceconfig" does not yield any official doc.

我对此类及其用法的一些疑问是:

Some of my questions about this class and its usage are:

  • ResourceConfig的子类中我可以做什么?
  • 我是否需要在某个地方注册ResourceConfig的子类以便可以找到它,或者它是否会被Jersey自动检测到?
  • 如果自动检测到该子类,如果我有多个ResourceConfig子类,会发生什么?
  • ResourceConfig的用途是否与web.xml文件相同?如果是这样,如果我两个都在我的项目中怎么办?他们中的一个优先于另一个吗?
  • What things can I do inside the subclass of ResourceConfig?
  • Do I need to register the subclass of ResourceConfig somewhere so that it can be found or is it automatically detected by Jersey?
  • If the subclass is automatically detected what happens if I have multiple subclasses of ResourceConfig?
  • Is the purpose of ResourceConfig the same as the web.xml file? If so what happens if I have both in my project? Does one of them take precedence over the other?

推荐答案

标准JAX-RS使用 ResourceConfig 扩展 Application.

Standard JAX-RS uses an Application as its configuration class. ResourceConfig extends Application.

(在servlet容器中)有三种主要的不同配置方式来配置Jersey(JAX-RS):

There are three main different ways (in a servlet container) to configure Jersey (JAX-RS):

  1. 仅使用web.xml
  2. 同时具有web.xml 一个Application/ResourceConfig
  3. 只有带有@ApplicationPath注释的Application/ResourceConfig类.
  1. With only web.xml
  2. With both web.xml and an Application/ResourceConfig class
  3. With only an Application/ResourceConfig class annotated with @ApplicationPath.

仅使用web.xml

可以用标准的JAX-RS方式配置应用程序,但以下内容仅适用于泽西岛

With only web.xml

It is possible to configure the application in a standard JAX-RS way, but the following is specific to 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运行是正确的. ServletContainer是处理传入请求的Jersey Servlet.因此,这里我们将其声明为<servlet-class>.我们还配置了<init-param>告诉Jersey哪些软件包可以扫描我们的@Path@Provider类,以便可以注册它们.

Since Jersey runs in a servlet container, it is only right that the Jersey application runs as a servlet. The Jersey Servlet that handles incoming requests is the ServletContainer. So here we declare it as the <servlet-class>. We also configure an <init-param> telling Jersey which package(s) to scan for our @Path and @Provider classes so it can register them.

在后台,Jersey实际上会创建一个ResourceConfig实例,因为它是用来配置应用程序的.然后它将注册通过程序包扫描发现的所有类.

Under the hood, Jersey will actually create a ResourceConfig instance, as that's what it uses to configure the application. Then it will register all the classes that it discovers through the package scan.

如果要使用ApplicationResourceConfig子类以编程方式配置应用程序,则可以对上面的web.xml进行一次更改.代替设置init-param来扫描软件包,我们使用init-param声明我们的Application/ResourceConfig子类.

If we want to programmatically configure our application with an Application or ResourceConfig subclass, we can do so with one change to the above web.xml. Instead of setting an init-param to scan for packages, we use an init-param to declare our Application/ResourceConfig subclass.

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

在这里,我们用ResourceConfig子类的完全限定名称配置init-param javax.ws.rs.Application.而且,我们没有使用init-param告诉泽西要扫描哪个软件包,而是使用了ResourceConfig的便捷方法packages().

Here, we configure the init-param javax.ws.rs.Application with the fully qualified name of our ResourceConfig subclass. And instead of using the init-param that tells Jersey which package(s) to scan, we just use the convenience method packages() of the ResourceConfig.

我们还可以使用方法register()property()来注册资源和提供程序,以及配置Jersey属性.使用property()方法,也可以使用property()方法来配置可以配置为init-param的任何内容.例如,我们可以不用调用packages(),而可以

We could also use the methods register() and property() to register resources and providers, and to configure Jersey properties. With the property() method, anything that can be configured as an init-param, can also be configured using the property() method. For instance instead of calling packages(), we could do

public JerseyApplication() {
    property("jersey.config.server.provider.packages",
             "com.mypackage.to.scan");
}

仅使用Application/ResourceConfig

没有web.xml,Jersey需要一种方式来提供servlet映射.我们使用@ApplicationPath批注来实现.

With only Application/ResourceConfig

Without a web.xml, Jersey needs a way for us to provide the servlet-mapping. We do this with the @ApplicationPath annotation.

// '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映射一样

Here with the @ApplicationPath, it's just like if we configured the servlet mapping in the web.xml

<servlet-mapping>
    <servlet-name>JerseyApplication</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

当仅使用Java代码进行配置时,Jersey需要某种方式来发现我们的配置类.这是通过使用 ServletContanerInitializer 完成的.这是Servlet 3.0规范中引入的,因此我们不能在较早的Servlet容器中使用仅Java"配置.

When using only Java code for configuration, there needs to be some way for Jersey to discover our configuration class. This is done with the use of a ServletContanerInitializer. This is something that was introduced in the Servlet 3.0 Specification, so we cannot use "Java only" configuration in earlier servlet containers.

基本上发生的是,初始化器的实现者可以告诉servlet容器寻找什么类,并且servlet容器会将这些类传递给初始化器onStartup()方法.在Jersey的初始化程序实现中,Jersey将其配置为查找Application类和带有@ApplicationPath注释的类.有关详细说明,请参见这篇文章.因此,当servlet容器启动应用程序时,Jersey的初始化程序将通过我们的Application/ResourceConfig类.

Basically what happens is that the implementor of the initializer can tell the servlet container what classes to look for, and the servlet container will pass those classes to the initializer onStartup() method. In Jersey's implementation of the initializer, Jersey configures it to look for Application classes and classes annotated with @ApplicationPath. See this post for further explanation. So when the servlet container starts the application, Jersey's initializer will get passed our Application/ResourceConfig class.

只需查看 javadoc .它主要只是课程注册.您不需要做很多其他事情.您将使用的主要方法是register()packages()property()方法. register()方法使您可以手动注册资源和提供程序的类和实例.前面讨论过的packages()方法列出了希望Jersey扫描@Path@Provider类并为您注册的软件包.并且property()方法允许您设置一些可配置的属性 1 .

Just look at the javadoc. Its mostly just registration of classes. Not much else you need to do with it. The main methods you will be using are the register(), packages(), and property() methods. The register() method lets you manually register classes and instances of resources and providers manually. The packages() method, discussed earlier, lists the package(s) you want Jersey to scan for @Path and @Provider classes and register them for you. And the property() method allows you to set some configurable properties 1.

ResourceConfig只是一个便利类.记住,它扩展了Application,所以我们甚至可以使用标准的Application

The ResourceConfig is just a convenience class. Remember, it extends Application, so we could even use the standard Application class

@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,我们就可以这样做

With a ResourceConfig, we would just do

public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        register(MyResource.class);
        register(new MyProvider());
        packages("com.mypackages.to.scan");
    }
}

除了更方便之外,还有一些东西可以帮助Jersey配置应用程序.

Aside from being more convenient, there are also a few thing under the hood that help Jersey configure the application.

以上所有示例均假设您在已安装的服务器环境中运行,例如雄猫.但是,您也可以在SE环境中运行该应用程序,在该环境中运行嵌入式服务器并从main方法启动该应用程序.有时,在搜索信息时有时会看到这些示例,所以我想展示一下它的外观,以便每当您遇到此问题时,您都不会感到惊讶,并且知道它与您的设置有何不同.

All the examples above assume you are running in an installed server environment, e.g. Tomcat. But you can also run the app in an SE environment, where you run an embedded server and start the app from a main method. You will sometimes see these examples when searching around for info, so I want to show what that looks like, so that when you every do come across this, you are not surprised and know how it differs from your setup.

所以有时您会看到类似的示例

So sometimes you will see an example like

ResourceConfig config = new ResourceConfig();
config.packages("com.my.package");
config.register(SomeFeature.class);
config.property(SOME_PROP, someValue);

这里最有可能发生的是该示例使用的是嵌入式服务器,例如Grizzly.启动服务器的其余代码可能类似于

What is most likely happening here is that the example is using an embedded server, like Grizzly. The rest of the code to start the server might be something like

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,而只是实例化了它.如果要做的话没什么不同

So in this example, there is a standalone server being started and the ResourceConfig is used to configure Jersey. The different here and from previous examples is that in this example, we are not extending the ResourceConfig, but instead just instantiating it. It wouldn't be any different if we were to do

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.因此,这就是为什么我增加了这一小部分的原因;所以你不会犯同样的错误.

Say you were going through some tutorial, and it showed a configuration for a standalone app, where they instantiate the ResourceConfig, but you are running your app in a servlet container and have been using the earlier configuration where you are extending the ResourceConfig. Well now you know what the difference is and what changes you need to make. I've seen people do some really weird stuff because they didn't understand this difference. For example I saw someone instantiating a ResourceConfig inside a resource class. So this is why I added this extra little piece; so you don't make the same mistake.

1.有许多不同的可配置属性.指向 ServerProperties 的链接只是一些常规属性.还有与特定功能相关的不同属性.该文档应在与该功能相关的文档部分中提及这些属性.有关所有可配置属性的完整列表,可以查看所有 Jersey常数,然后查找字符串值以jersey.config开头的常数.如果使用的是web.xml,则可以将字符串值用作init-param param-name.如果使用的是Java config(ResourceConfig),则将调用property(ServerProperties.SOME_CONF, value)

1. There are a number of different configurable properties. The link to the ServerProperties are just some general properties. There are also different properties related to specific features. The documentation should mention these properties in the section of the docs related to that feature. For a complete list of all configurable properties, you can look at all the Jersey constants and look for the ones where the string value starts with jersey.config. If you are using a web.xml, then you would use the string value as the init-param param-name. If you are using Java config (ResourceConfig), then you would call property(ServerProperties.SOME_CONF, value)

这篇关于泽西岛2中的ResourceConfig类到底是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆