Data AccessCore JavaApp FrameworksViewTestingBuildingDeploymentDev ToolsSecurityOpinions

Saturday, November 6, 2010

JAX-RS @Path Precedence Rules

The other day I needed to figure out how the JAX-RS provider resolves ambiguous path expressions passed in the @javax.ws.rs.Path annotation. I learned about the provider's precedence rules and wanted to document them here with a short example.

For example, say we have the following @javax.ws.rs.Path expressions in the following class:

@Path("/users") 
public class UserResource {

  @GET
  @Path("{id : .+}")
  public String getUser(@PathParam("id") String id){
    ....
  }


  @GET
  @Path("{id : .+}/address")
  public String getAddress(@PathParam("id") String id){
    ....
  }
}

Note that .+ will match any stream of characters after "/users".
Now, suppose the following GET request was submitted.

GET /users/32/address

The request actually matches both expressions, but the request would be routed to the getAddress(@PathParam("id") String id) method. The JAX-RS provider determines which method to call based on a set of precedence rules. On deployment, the JAX-RS provider gathers and sorts all URI expressions contained within all known @Path annotations based on the following logic:

  1. The number of literal characters contained within the expression, sorted in descending order. In the example above, the getAddress(@PathParam("id") String id) method gets precedence over the getUser(@PathParam("id") String id) method. The getUser(@PathParam("id") String id) method contains 7 literal characters (/users/). The getAddress @PathParam("id") String id) method contains 14 literal characters (/users/ + address).
  2. The number of template expressions within the expression, sorted in descending order. For example, an expression containing {id}/{name} would get precedence over {id}.
  3. Finally, the number of regular expressions contained within the expression. For example, {id : .+} would get precedence over {id}.

In closing, the following URI expressions are sorted by the order of precedence above.

  1. /users/{id}/{name}/address
  2. /users/{id : .+}/address
  3. /users/{id}/address
  4. /users/{id : .+}

Any questions, leave a comment and I'll be sure to answer.

0 comments:

Post a Comment