关于Java:如何在没有web.xml的情况下将Jersey用作JAX-RS实现?

How to use Jersey as JAX-RS implementation without web.xml?

我从JavaEE 6中了解到web.xml是可选的。

因此,如果没有web.xml,我如何告诉应用程序服务器使用Jersey作为JAX-RS规范的实现?


@AlexNevidomsky在回答中写的是正确的,就如何在没有web.xml的情况下实现应用程序配置而言;您在Application子类上使用@ApplicationPath注释。

1
2
@ApplicationPath("/api")
public class AppConfig extends Application {}

有关部署选项的更多信息,请参见Jersey Docs:第4章。应用程序部署和运行时环境

或更常见的是,以Jersey作为实现,我们将扩展ResourceConfig(扩展了Application)。

1
2
3
4
5
6
@ApplicationPath("api")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        packages("package.to.scan");
    }
}

那么这是如何实现的...

首先,并非所有Java EE服务器都使用Jersey。实际上,我所知道的唯一使用Jersey的是Glassfish和WebLogic。 JBoss使用Resteasy。 Tom EE使用CXF。 WebSphere使用Apache Wink。这些是我唯一想到的。

所以我想这个问题是"服务器如何知道如何加载JAX-RS应用程序?"

Servlet 3.0引入了可插入性机制,该机制利用了ServletContainerInitializer。它的工作方式是,当启动Server / Servlet容器时,它将在jars中扫描名为javax.servlet.ServletContainerInitializer的文件的META-INF/services文件夹。该文件应包含一个或多个ServletContainerInitializer实现的标准名称。

此界面只有一种方法

1
void onStartup(java.util.Set<java.lang.Class< ? >> c, ServletContext ctx)

Set<Class<?>将是一个类列表,适合ServletContainerInitializer实现上@HandlesTypes批注中的条件。如果您看泽西岛的实现

1
2
3
@HandlesTypes({ Path.class, Provider.class, Application.class, ApplicationPath.class })
public final class JerseyServletContainerInitializer
                   implements ServletContainerInitializer {

您应该注意到一些熟悉的注释类以及Application.class。在扫描时,所有符合条件的所有类都将添加到传递给onStartup方法的Set中。

如果您扫描其余的源代码,则将看到所有这些类的所有注册都已完成。

Resteasy使用

1
2
@HandlesTypes({Application.class, Path.class, Provider.class})
public class ResteasyServletInitializer implements ServletContainerInitializer

我不会和别人见面的。

您可以查看某些资料...

  • JerseyServletContainerInitializer源代码
  • ResteasyServletInitializer源代码
  • JAX-RS规格


您不必在web.xml中指定任何内容。定义一个激活器类:

1
2
3
4
5
6
7
8
@ApplicationPath("/rest")
public class _JaxRsActivator extends javax.ws.rs.core.Application {

  static {
      //Check some system init on REST init.
      Config.initCheck();
  }
}