REST 子资源定位器

REST Subresource Locators

我正在通读 RESTful Java 和 JAX-RS 2.0,第 2 版 这本书,并且正在努力理解子资源定位器的工作原理,如下所示是所提供示例的简化版本。

CustomerDatabaseResource class

@Path("/customers")
public class CustomerDatabaseResource {

   @Path("{database}-db")
   public CustomerResource getDatabase(@PathParam("database") String db) {
      // find the instance based on the db parameter
      CustomerResource resource = locateCustomerResource(db);
      return resource;
   }

   protected CustomerResource locateCustomerResource(String db) {
     ...
   }
}

客户资源Class

public class CustomerResource {
   private Map<Integer, Customer> customerDB =
                          new ConcurrentHashMap<Integer, Customer>();
   private AtomicInteger idCounter = new AtomicInteger();

   public CustomerResource(Map<Integer, Customer> customerDB)
   {
      this.customerDB = customerDB;
   }

   @GET
   @Path("{id}")
   @Produces("application/xml")
   public StreamingOutput getCustomer(@PathParam("id") int id) {
     ...
   }

所以我了解到,当 GET /customers/northamerica-db/333 之类的请求传入时,将首先匹配方法 CustomerDatabaseResource.getDatabase() 上的表达式,该方法将根据位置创建正确的 CustomerResource 实例。

我不明白的是接下来会发生什么...

  1. 实例resource被返回,但返回到哪里?

  2. Web服务如何知道然后用方法CustomerResource.getCustomer()匹配和处理请求的剩余部分?我想这是因为 CustomerDataBaseResource class 没有 @GET,但我真的不明白转换是如何发生的。

  3. 这是 RESTEasy 特有的吗?

  1. The instance resource gets returned, but returned to where?

它被 return 发送到请求处理引擎并继续寻找匹配方法(在 return 资源对象内),就像任何其他请求一样。

  1. How does the web service know to then match and process the remaining part of the request with the method CustomerResource.getCustomer()? I guess this is because The CustomerDataBaseResource class doesn't have a @GET, but I don't really understand how the transition happens

资源定位器不应使用 Http 方法进行注释。这就是他们被称为定位器的原因。既然不是要调用的资源方法,就不应该注解。想象一下

public class CustomerResource {
    @PUT
    @Path("{id}")
    public Response updateCustomer(Customer customer) {}
    @POST
    @Path("{id}")
    public Response createCustomer(Customer customer) {}
}

如果CustomerDataBaseResource.getDatabase()要注解一个Http方法,那我们就打不到上面的方法了。定位器只需要 @Path,URI 匹配将从该路径开始继续。

/customers/database-us

一旦CustomerResource被创建,如果请求uri是/customers/database-us/123,那么现在下一个合乎逻辑的步骤是根据URI找到匹配的资源方法,所以会寻找一些东西用 @Path 注释将匹配 123。然后检查Http方法。

  1. Is this specific to RESTEasy?

正在经历 jax-rs spec, I don't see anything about sub-resource locators, but Jersey also implements this exact behavior。我读过你所指的书,据我所知,作者并没有真正深入了解任何特定于实现的内容,但确实提到了大多数实现者实现的共同特征,这不是规范的一部分。也许这就是其中之一。


更新

所以它在规范中。转到 link 并下载规范。您将在 3.4.1 Sub Resources 下找到所有内容,并在 3.7.2 Request Matching

中找到请求匹配的一些算法信息