是否可以定义一个与其实现分离的 jax-rs 服务接口(使用 eclipse 和 jersey)?

Posted

技术标签:

【中文标题】是否可以定义一个与其实现分离的 jax-rs 服务接口(使用 eclipse 和 jersey)?【英文标题】:Is it possible to define a jax-rs service interface separated from its implementation (with eclipse and jersey)? 【发布时间】:2013-06-01 19:11:00 【问题描述】:

我不知道标题是否令人困惑,但假设我有这个界面:

@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
public interface UserService 

    @GET
    @Path("/userId")
    public Response getUser(@PathParam("userId") Long userId);


为什么当我尝试实现一个版本时,Eclipse 会为被覆盖的方法而不是类重写注释?

class UserServiceImpl implements UserService 

    @Override
    @GET
    @Path("/userId")
    public Response getUser(@PathParam("userId") Long userId) 
        // TODO Auto-generated method stub
        return null;
    


我试图为 restful web 服务创建一个标准定义,然后有不同的实现。使用标准 jax-rs 可以实现这样的事情吗?我是否有任何机会使用错误的注释?

【问题讨论】:

【参考方案1】:

只有在实现类上不使用 any jax-rs 注释时,才能使用注释继承:在 JSR-339 的第 3.6 节中有说明。

您为方法重新定义了@Path@Produces,但没有为类重新定义。

所以你代码中的Path注解应该在具体类上:

public interface UserService 

    @GET
    @Path("/userId")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUser(@PathParam("userId") Long userId);




@Path("/user")
class UserServiceImpl implements UserService 

    @Override
    @GET
    @Path("/userId")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUser(@PathParam("userId") Long userId) 
        // TODO Auto-generated method stub
        return null;
    


顺便说一句,规范鼓励我们在具体类上复制注释:

为了与其他 Java EE 规范保持一致,建议始终重复注释而不是 依赖注解继承。

【讨论】:

您实际上不需要在界面和混凝土上都添加注释。除了类上的@Path(@Path(“/user”))之外,您可以将所有内容都放在界面上。 我的意思是你可以把它留在界面上而不是混凝土上。通过这种方式,您可以使接口可用于客户端代理。 @shlomi33 你是对的,但这不是一种鼓励的做法。也许在最后一次编辑之后更好地说明。 我发现如果我在接口方法上而不是在实现类方法上添加 POST 和 PathParam,我会得到 404。(使用球衣,灰熊)。 这个答案中提到的引用可以在这个文档(pdf)的 3.6 Annotation Inheritance 中找到:download.oracle.com/otn-pub/jcp/jaxrs-2_0-edr2-spec/…【参考方案2】:

我在使用 OpenAPI 生成器自动生成的界面时遇到了类似的问题。这里的问题是我不能轻易地从接口中删除 @Path 注释,另外将其添加到类中会导致歧义问题。

@Path-annotated 接口的问题只发生在注册包上自动发现的资源上。对于已注册的包,所有带有 @Path 注释的类(不幸的是接口也是如此)都将被实例化。

为防止这种情况发生,您可以使用 ResourceConfig 手动注册资源,如下例所示:

new ResourceConfig()
    .registerClasses(UserServiceImpl.class);

请确保您的接口不在使用您的ResourceConfig 注册的包中。使用这种方法,您可以使用示例中的实现,并且添加到接口的 @Path 注释将被正确解释。

免责声明:接口上可能不应该有任何@Path 路径注释,但不幸的是,这是 OpenAPI 生成器创建的。如果您发现自己处于类似情况,我希望这会有所帮助。否则,您应该参考接受的答案。

【讨论】:

以上是关于是否可以定义一个与其实现分离的 jax-rs 服务接口(使用 eclipse 和 jersey)?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 JAX-RS Web 服务部署到 MobileFirst Server?

JAX-RS入门 二 :运行

如何使用 JAX-RS 异常上的自定义消息设置 40X 错误?

从JAX-RS服务发送重定向

restful基础

在 JAX-RS 中使用 API 密钥进行身份验证