是否有可能将jax-rs服务接口与其实现分离(使用eclipse和jersey)



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

@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是否可能实现这样的功能?我用错注释了吗?

只有在实现类上不使用任何 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规范保持一致,建议始终重复注释依赖于注释继承。

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

然而,@Path注释接口的问题只发生在注册包上自动发现的资源上。对于已注册的包,所有带有@Path注释的类(不幸的是还有接口)都将被实例化。 为了防止这种情况,你可以在ResourceConfig中手动注册资源,如下例所示:
new ResourceConfig()
    .registerClasses(UserServiceImpl.class);

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

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

最新更新