【问题标题】:How to annotate JAX-RS on an interface while using Jersey使用 Jersey 时如何在接口上注释 JAX-RS
【发布时间】:2016-11-29 22:32:33
【问题描述】:

这个问题已被问过几次before,但答案似乎不起作用和/或泽西岛已经进行了更多更改。

我正在使用 JAX-RS 和 Jersey(版本 2.24)公开一些 REST API。我希望用 JAX-RS 和具体实现来注释接口(没有任何注释)。然而,由于this patch Jersey 不再支持这种可能性。据我了解spec,并没有严格禁止这样做。

如果子类或实现方法有任何 JAX-RS 注释,则忽略超类或接口方法上的所有注释。

暗示这样做是完全可以的。在许多情况下,最好使用接口,并让服务器和客户端各自拥有各自的实现。

有很多解决方案,

  1. 使用 ResourceConfig 并执行 registerClasses(MyImplementation.class) 。但是,这不起作用。
  2. 禁用web.xml 中的包扫描配置,创建自定义javax.ws.rs.Application 并从那里执行您的实现register。不起作用。
  3. 使用ResourceConfig 并定义自定义AbstractBinder 并执行bind 以便Jersey 的依赖注入可以找到具体实现。不起作用。
  4. 使用 RESTEasy。 RESTEasy 似乎没有像 Jersey 那样强加接口限制。自己从未尝试过。

如果有人能分享他们的经验,我将不胜感激。关于如何让泽西岛工作的任何帮助也会很棒。至于选项(4)是否真的需要切换?下面的示例代码。

MyResource

 package com.foo;

import javax.ws.rs.GET;
import javax.ws.rs.Path;


@Path("/hello")
public interface MyResource {

  @GET
  public String sayHello();

}

MyResourceImpl

package com.bar;

public class MyResourceImpl implements MyResource {

  @Override
  public String sayHello() {
    return "Hello Jersey";
  }
}

还有一个 web.xml 启用包扫描以扫描 com.foo

【问题讨论】:

  • 它不适用于具体类而不是接口上的类级别@Path。这就是我一直知道它的工作方式(如 JAX-RS 规范中所述)。我什至不知道曾经支持接口类 anno。
  • @dur 是的,cxf 或 resteasy 可能支持这一点。我相信 jersey 比 cxf 更容易设置。
  • @peeskillet 它与具体类上的@Path 注释一起使用。但这违背了在我的案例中使用接口的目的。客户端和服务器必须使用相同的 API 路径。使用您的解决方案,我最终会为客户端复制路径(我的客户端是从 swagger 规范生成的 javascript 代码)
  • 来自您引用的 JAX-RS 规范的同一段:JAX-RS annotations may be used on the methods and method parameters of a super-class or an implemented interface 请注意,它仅表示 methods,因此接口上的类级别注释暗示为忽略。

标签: java rest jersey jax-rs jersey-2.0


【解决方案1】:

在泽西岛,我们应该把类级别的@Path 放在实现而不是接口上。

包 com.foo;

import javax.ws.rs.GET;
import javax.ws.rs.Path;


@Path("/hello")
public interface MyResource {

  @GET
  public String sayHello();

}


MyResourceImpl

package com.bar;
@Path("/hello")
public class MyResourceImpl implements MyResource {

  @Override
  public String sayHello() {
    return "Hello Jersey";
  }
}

【讨论】:

  • 我知道它是这样工作的。请在上面查看我的 cmets @peeskillet。
  • 有人能解决这个问题吗?我不想在类和接口中重复注释@Path。
【解决方案2】:

如果您想将 Resource 接口与实现分开(允许您将该接口与一些 REST 客户端(如 resteasy 客户端)一起使用),您可以在实现上使用 @RequestScoped。因此,这个 bean 可以使用注入的资源,如 EJB、EntityManager、... 使用您的样本:

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/hello")
public interface MyResource {

   @GET
   public String sayHello();
}

MyResourceImpl

package com.bar;

@RequestScoped
public class MyResourceImpl implements MyResource {

  @Override
  public String sayHello() {
    return "Hello Jersey";
  }
}

尽管如此,您必须考虑到,一旦您在实现代码中使用特定的 JAX-RS 类(如 UriInfo、Response 对象等),您将在您的实现和 JAX-RS 之间建立耦合API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-08
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多