5

假设我有一组 JAX-RS 定位器和子定位器,如下所示:

@Path("/users")
public class UserListResource {
   @Path("/{id}")
   public UserResource getCustomer(@PathParam("id") int id) {
      // Find and return user object
   }
}

public class UserResource {
  @GET
  public String get() {...}
}

例如,UserResource具有 ID 的对象5将具有路径"/users/5"。在我的系统中,我有几个不同的资源。

现在的问题是:服务器如何找出给定资源的路径?我可以通过一些 JAX-RS API 以编程方式执行此操作,还是必须实现使用反射的代码?(我知道如何做后者,但更喜欢另一种方法。)

  • 在我需要知道路径的时候,我根本没有请求对象。例如,我有一个计时器,它进行一些后台处理,然后更改域模型中的一些实体,然后通知所有客户端有关更改的实体(包括它们的路径)。
  • 我知道在请求的范围内,我可以注入UriInfo提供此功能的对象,但我需要提前知道路径(以通知客户端不一定通过 JAX-RS 资源发生的更改)。
  • 我不想在另一个地方重复路径信息,也不想为每种资源类型(在本例中为"/users"and "/{id}")设置一组路径片段常量。
4

4 回答 4

3

当我阅读您的问题时,您需要构建一个只知道资源类和id参数的 URI。

可以使用UriBuilder 类来完成,如下所示:

UriBuilder builder=UriBuilder.fromResource(UserListResource.class);
URI uri=builder.path(UserListResource.class,"getCustomer").build(5);

它在引擎盖下使用反射,因此重构并不容易,但它是目前可用的全部。

于 2013-02-04T10:22:42.630 回答
1

总的来说,请注意,您的应用程序架构听起来有些奇怪。很难说清楚,但你提出的问题模式正在引发一些关于你如何处理这件事的危险信号。请注意,如果您正在寻求为您的应用程序创建一个可能需要停止的 RESTful API,请退后几步,重新考虑您正在尝试做什么。

对于你明确的问题......</p>

现在的问题是:服务器如何找出给定资源的路径?我可以通过一些 JAX-RS API 以编程方式执行此操作,还是必须实现使用反射的代码?(我知道如何做后者,但更喜欢另一种方法。)

服务器知道路径,因为它始终由用户提供,并用于在构成应用程序的资源类集合中导航。如果您需要UriInfo特定调用的实例,则应将其作为该特定调用的一部分注入:

@GET
public String get(@Context UriInfo info) {...}

外部上下文所需的任何信息(例如,资源的 ID 是什么)最好在构造期间传递。您可以再次从 URL 中重新解析它(可从 中获得UriInfo),但这可能是错误的方法。

否则,如果您正在做一些更复杂的事情,那么您需要在您的问题中更加具体。

  • 在我需要知道路径的时候,我根本没有请求对象。例如,我有一个计时器,它进行一些后台处理,然后更改域模型中的一些实体,然后通知所有客户端有关更改的实体(包括它们的路径)。
  • 我知道在请求的范围内,我可以注入UriInfo提供此功能的对象,但我需要提前知道路径(以通知客户端不一定通过 JAX-RS 资源发生的更改)。

你将如何通知客户?通常没有将消息从服​​务器推送到客户端的机制,并且客户端通常有防火墙,因此它们不能直接托管服务。

从理论上讲,您可以(明确地,通过 URL)将每个资源与其自己的 RSS 提要相关联,如果客户愿意,他们可以收听这些提要。你不能强迫客户倾听,但你可以让他们选择这样做。如果你走这条路,你不需要知道UriInfo“提前”,因为位置信息将出现在关键时间(即资源创建时),然后你只是指的是你可以控制的东西.

但这只是一种方法,它增加了很多复杂性;只有当它对您的应用程序至关重要时,您才会这样做。让客户不时进行轮询通常更简单。(请注意,某些类型的修改本质上是非常具有破坏性的;尤其是更改 ID 或删除资源。不要指望事情能顺利应对。)

  • 我不想在另一个地方重复路径信息,我也不想为每种资源类型(在本例中为“ /users”和“ /{id}”)设置一组路径片段常量。

艰难的。在多个地方重复信息,前提是您始终从单一来源获取信息,这是一种常见的做法。它实际上并没有什么问题。

于 2013-02-04T11:25:33.010 回答
0

据我了解您的问题,您想知道请求进入但在它到达您的资源之前的路径;你愿意使用 Servlet 过滤器吗?

仅在 2.0 中支持 JAX-RS 特定过滤器

于 2013-01-31T10:29:38.643 回答
0

作为记录:在我发布问题后,我对我们的架构进行了更多思考,并得出结论,发送 URLS 并没有我想象的那么有用。无论如何,应用程序必须知道有关应用程序结构的一些细节:

  • 继续上面的例子:即使客户端不知道单个用户的 URL 模式,它也必须假设有一个用户列表并且知道它的 URL;它还具有硬编码的知识,要显示什么对话框来编辑用户等。

所以总而言之,试图告诉客户端(大多数)它需要的 URL 是不值得的。相反,我们决定使用自定义 API 定义文件,其中包含有关资源内容及其 URL 方案的数据。该文件用于生成以下内容:

  • 具有正确 JAX-RS 注释的服务器端资源类
  • 供其他开发人员编写代码的 URL 方案规范文档
  • 我们自己的客户端的类(包括 URL 知道如何,例如 ID 为 5 的用户拥有 URL ...),因此我们不必担心客户端和服务器之间的不一致。

这种方法具有以下优点:

  • 服务器从注释中找出 URL 的需求消失了,因为客户端现在可以在收到包含对象 ID 的通知后自行执行此操作。
  • 我们不必担心客户端和服务器之间的不一致,因为所有信息都来自单一来源。
  • 我们有一个版本控制下的 API 定义来源,可用于验证与旧版本的向后兼容性。

注意: 我可能不会声称生成的 API 对 RESTful Web 服务的想法保持“忠实”,但它对我们有用,并且它从“实际”REST 架构风格中借用的元素应该使 API 比传统的合同优先的 Web 服务。

于 2013-02-05T09:36:05.543 回答