【问题标题】:How to use Jersey as JAX-RS implementation without web.xml?如何在没有 web.xml 的情况下使用 Jersey 作为 JAX-RS 实现?
【发布时间】:2015-06-26 02:02:39
【问题描述】:

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

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

【问题讨论】:

    标签: java rest jakarta-ee jersey jax-rs


    【解决方案1】:

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

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

    有关部署选项的更多信息,请参阅Jersey Docs: Chapter 4. Application Deployment and Runtime Environments

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

    @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 容器时,它会扫描 jar 中的 META-INF/services 文件夹,其中包含一个名为 javax.servlet.ServletContainerInitializer 的文件。此文件应包含一个或多个 ServletContainerInitializer 实现的完全限定名称。

    这个接口只有一个方法

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

    Set&lt;Class&lt;?&gt; 将是一个类列表,符合ServletContainerInitializer 实现上的@HandlesTypes 注释中的标准。如果你看看 Jersey 的实现

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

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

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

    轻松使用

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

    我不会接触别人。

    您可以查看一些来源...

    【讨论】:

    • 那么,我可以在我的 Jersey 项目中删除 web.xml 吗?
    • @mFeinstein 您需要一个完整的 JAX-RS 实现。 Tomcat 没有。
    • 经过大量搜索,我使它与 HK2 DI 一起工作,在我的情况下(我使用 AWS Lambda Serverless Framework for Jersey 和 Tomcat 进行本地测试)我需要添加 implementation 'org.glassfish.jersey.containers:jersey-container-servlet:2.28' 并更改Windows 10 上的 Tomcat webapp 文件夹权限,因为 IntelliJ 无法在 Program Files 内部署。
    • @PaulSamsotha 奇怪的是,我无法让它在 GlassFish 5 上运行。如果我添加 HK2 DI,它会崩溃,我猜 GlassFish CDI 不能很好地配合它。
    • @mFeinstein 如果您使用 Maven,请将您的所有 Jersey 依赖项设置为 provided 范围。 Glassfish 的库中已经有了所有的罐子。你只需要它们来编译你的应用程序。
    【解决方案2】:

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

    @ApplicationPath("/rest")
    public class _JaxRsActivator extends javax.ws.rs.core.Application {
    
      static {
          //Check some system init on REST init.
          Config.initCheck();
      }
    }
    

    【讨论】:

    • 但是服务器怎么知道要使用球衣呢?
    • 如果您对技术细节感兴趣,请注意您在此处定义了路径映射。因此,在对该路径前缀的第一次请求时,会发生初始化:servlet 容器调用 ResteasyDeployment.start()。至少 JBoss 是这样做的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2022-10-16
    • 2016-09-23
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多