Red Hat DocumentationFuse ESBToggle FramesPrintFeedback

Injecting data from a request URI

Overview

One of the best practices for designing a RESTful Web service is that each resource should have a unique URI. A developer can use this principle to provide a good deal of information to the underlying resource implementation. When designing URI templates for a resource, a developer can build the templates to include parameter information that can be injected into the resource implementation. Developers can also leverage query and matrix parameters for feeding information into the resource implementations.

Getting data from the URI's path

One of the more common mechanisms for getting information about a resource is through the variables used in creating the URI templates for a resource. This is accomplished using the javax.ws.rs.PathParam annotation. The @PathParam annotation has a single parameter that identifies the URI template variable from which the data will be injected.

In Example 10 the @PathParam annotation specifies that the value of the URI template variable color is injected into the itemColor field.

Example 10. Injecting data from a URI template variable

import javax.ws.rs.Path;
import javax.ws.rs.PathParam
...

@Path("/boxes/{shape}/{color}")
class Box
{
  ...

  @PathParam("color")
  String itemColor;

  ...
}

The data types supported by the @PathParam annotation are different from the ones described in Supported data types. The entity into which the @PathParam annotation injects data must be of one of the following types:

  • PathSegment

    The value will be the final segment of the matching part of the path.

  • List<PathSegment>

    The value will be a list of PathSegment objects corresponding to the path segment(s) that matched the named template parameter.

  • primitives such as int, char, or long

  • Objects that have a constructor that accepts a single String argument

  • Objects that have a static valueOf() method that accepts a single String argument

Using query parameters

A common way of passing information on the Web is to use query parameters in a URI. Query parameters appear at the end of the URI and are separated from the resource location portion of the URI by a question mark(?). They consist of one, or more, name value pairs where the name and value are separated by an equal sign(=). When more than one query parameter is specified, the pairs are separated from each other by either a semicolon(;) or an ampersand(&). Example 11 shows the syntax of a URI with query parameters.

Example 11. URI with a query string

http://fusesource.org?name=value;name2=value2;...

Note

You can use either the semicolon or the ampersand to separate query parameters, but not both.

The javax.ws.rs.QueryParam annotation extracts the value of a query parameter and injects it into a JAX-RS resource. The annotation takes a single parameter that identifies the name of the query parameter from which the value is extracted and injected into the specified field, bean property, or parameter. The @QueryParam annotation supports the types described in Supported data types.

Example 12 shows a resource method that injects the value of the query parameter id into the method's id parameter.

Example 12. Resource method using data from a query parameter

import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...

@Path("/monstersforhire/")
public class MonsterService
{
  ...
  @POST
  @Path("\{type}")
  public void updateMonster(@PathParam("type") String type,
                            @QueryParam("id") String id)
  {
    ...
  }
  ...
}

To process an HTTP POST to /monstersforhire/daikaiju?id=jonas the updateMonster() method's type is set to daikaiju and the id is set to jonas.

Using matrix parameters

URI matrix parameters, like URI query parameters, are name/value pairs that can provide additional information selecting a resource. Unlike query parameters, matrix parameters can appear anywhere in a URI and they are separated from the hierarchical path segments of the URI using a semicolon(;). /mostersforhire/daikaiju;id=jonas has one matrix parameter called id and /monstersforhire/japan;type=daikaiju/flying;wingspan=40 has two matrix parameters called type and wingspan.

Note

Matrix parameters are not evaluated when computing a resource's URI. So, the URI used to locate the proper resource to handle the request URI /monstersforhire/japan;type=daikaiju/flying;wingspan=40 is /monstersforhire/japan/flying.

The value of a matrix parameter is injected into a field, parameter, or bean property using the javax.ws.rs.MatrixParam annotation. The annotation takes a single parameter that identifies the name of the matrix parameter from which the value is extracted and injected into the specified field, bean property, or parameter. The @MatrixParam annotation supports the types described in Supported data types.

Example 13 shows a resource method that injects the value of the matrix parameters type and id into the method's parameters.

Example 13. Resource method using data from matrix parameters

import javax.ws.rs.MatrixParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...

@Path("/monstersforhire/")
public class MonsterService
{
  ...
  @POST
  public void updateMonster(@MatrixParam("type") String type,
                            @MatrixParam("id") String id)
  {
    ...
  }
  ...
}

To process an HTTP POST to /monstersforhire;type=daikaiju;id=whale the updateMonster() method's type is set to daikaiju and the id is set to whale.

Note

JAX-RS evaluates all of the matrix parameters in a URI at once, so it cannot enforce constraints on a matrix parameters location in a URI. For example /monstersforhire/japan;type=daikaiju/flying;wingspan=40 , /monstersforhire/japan/flying;type=daikaiju;wingspan=40, and /monstersforhire/japan;type=daikaiju;wingspan=40/flying are all treated as equivalent by a RESTful Web service implemented using the JAX-RS APIs.

Disabling URI decoding

By default all request URIs are decoded. So the URI /monster/night%20stalker and the URI /monster/night stalker are equivalent. The automatic URI decoding makes it easy to send characters outside of the ASCII character set as parameters.

If you do not wish to have URI automatically decoded, you can use the javax.ws.rs.Encoded annotation to deactivate the URI decoding. The annotation can be used to deactivate URI decoding at the following levels:

  • class level—Decorating a class with the @Encoded annotation deactivates the URI decoding for all parameters, field, and bean properties in the class.

  • method level—Decorating a method with the @Encoded annotation deactivates the URI decoding for all parameters of the class.

  • parameter/field level—Decorating a parameter or field with the @Encoded annotation deactivates the URI decoding for all parameters of the class.

Example 14 shows a resource whose getMonster() method does not use URI decoding. The addMonster() method only disables URI decoding for the type parameter.

Example 14. Disabling URI decoding

@Path("/monstersforhire/")
public class MonsterService
{
  ...

  @GET
  @Encoded
  @Path("\{type}")
  public Monster getMonster(@PathParam("type") String type,
                            @QueryParam("id") String id)
  {
    ...
  }

  @PUT
  @Path("\{id}")
  public void addMonster(@Encoded @PathParam("type") String type,
                         @QueryParam("id") String id)
  {
    ...
  }
  ...
}

Error handling

If an error occurs when attempting to inject data using one of the URI injection annotations a WebApplicationException exception wraps the original exception is generated. The WebApplicationException exception's status is set to 404.

Comments powered by Disqus