Chapter 52. Getting and Using Context Information

Abstract

Context information includes detailed information about a resource’s URI, the HTTP headers, and other details that are not readily available using the other injection annotations. Apache CXF provides special class that amalgamates the all possible context information into a single object.

52.1. Introduction to contexts

Context annotation

You specify that context information is to be injected into a field or a resource method parameter using the javax.ws.rs.core.Context annotation. Annotating a field or parameter of one of the context types will instruct the runtime to inject the appropriate context information into the annotated field or parameter.

Types of contexts

Table 52.1, “Context types” lists the types of context information that can be injected and the objects that support them.

Table 52.1. Context types

ObjectContext information

UriInfo

The full request URI

HttpHeaders

The HTTP message headers

Request

Information that can be used to determine the best representation variant or to determine if a set of preconditions have been set

SecurityContext

Information about the security of the requester including the authentication scheme in use, if the request channel is secure, and the user principle

Where context information can be used

Context information is available to the following parts of a JAX-RS application:

  • resource classes
  • resource methods
  • entity providers
  • exception mappers

Scope

All context information injected using the @Context annotation is specific to the current request. This is true in all cases including entity providers and exception mappers.

Adding contexts

The JAX-RS framework allows developers to extend the types of information that can be injected using the context mechanism. You add custom contexts by implementing a Context<T> object and registering it with the runtime.

52.2. Working with the full request URI

Abstract

The request URI contains a significant amount of information. Most of this information can be accessed using method parameters as described in Section 47.2.2, “Injecting data from a request URI”, however using parameters forces certain constraints on how the URI is processed. Using parameters to access the segments of a URI also does not provide a resource access to the full request URI.

You can provide access to the complete request URI by injecting the URI context into a resource. The URI is provided as a UriInfo object. The UriInfo interface provides functions for decomposing the URI in a number of ways. It can also provide the URI as a UriBuilder object that allows you to construct URIs to return to clients.

:experimental:

52.2.1. Injecting the URI information

Overview

When a class field or method parameter that is a UriInfo object is decorated with the @Context annotation, the URI context for the current request is injected into the UriInfo object.

Example

Injecting the URI context into a class field shows a class with a field populated by injecting the URI context.

Injecting the URI context into a class field

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Path;
...
@Path("/monstersforhire/")
public class MonsterService
{
  @Context
  UriInfo requestURI;
  ...
}

52.2.2. Working with the URI

Overview

One of the main advantages of using the URI context is that it provides access to the base URI of the service and the path segment of the URI for the selected resource. This information can be useful for a number of purposes such as making processing decisions based on the URI or calculating URIs to return as part of the response. For example if the base URI of the request contains a .com extension the service may decide to use US dollars and if the base URI contains a .co.uk extension is may decide to us British Pounds.

The UriInfo interface provides methods for accessing the parts of the URI:

  • the base URI
  • the resource path
  • the full URI

Getting the Base URI

The base URI is the root URI on which the service is published. It does not contain any portion of the URI specified in any of the service’s @Path annotations. For example if a service implementing the resource defined in Example 47.5, “Disabling URI decoding” were published to http://fusesource.org and a request was made on http://fusesource.org/montersforhire/nightstalker?12 the base URI would be http://fusesource.org.

Table 52.2, “Methods for accessing a resource’s base URI” describes the methods that return the base URI.

Table 52.2. Methods for accessing a resource’s base URI

MethodDesription

URIgetBaseUri

Returns the service’s base URI as a URI object.

UriBuildergetBaseUriBuilder

Returns the base URI as a javax.ws.rs.core.UriBuilder object. The UriBuilder class is useful for creating URIs for other resources implemented by the service.

Getting the path

The path portion of the request URI is the portion of the URI that was used to select the current resource. It does not include the base URI, but does include any URI template variable and matrix parameters included in the URI.

The value of the path depends on the resource selected. For example, the paths for the resources defined in Getting a resource’s path would be:

  • rootPath/monstersforhire/
  • getterPath/mostersforhire/nightstalker

    The GET request was made on /monstersforhire/nightstalker.

  • putterPath/mostersforhire/911

    The PUT request was made on /monstersforhire/911.

Getting a resource’s path

@Path("/monstersforhire/")
public class MonsterService
{
  @Context
  UriInfo rootUri;

  ...

  @GET
  public List<Monster> getMonsters(@Context UriInfo getUri)
  {
    String rootPath = rootUri.getPath();
    ...
  }

  @GET
  @Path("/{type}")
  public Monster getMonster(@PathParam("type") String type,
                            @Context UriInfo getUri)
  {
    String getterPath = getUri.getPath();
    ...
  }

  @PUT
  @Path("/{id}")
  public void addMonster(@Encoded @PathParam("type") String type,
                         @Context UriInfo putUri)
  {
    String putterPath = putUri.getPath();
    ...
  }
  ...
}

Table 52.3, “Methods for accessing a resource’s path” describes the methods that return the resource path.

Table 52.3. Methods for accessing a resource’s path

MethodDesription

StringgetPath

Returns the resource’s path as a decoded URI.

StringgetPathbooleandecode

Returns the resource’s path. Specifying false disables URI decoding.

List<PathSegment>getPathSegments

Returns the decoded path as a list of javax.ws.rs.core.PathSegment objects. Each portion of the path, including matrix parameters, is placed into a unique entry in the list.

For example the resource path box/round#tall would result in a list with three entries: box, round, and tall.

List<PathSegment>getPathSegmentsbooleandecode

Returns the path as a list of javax.ws.rs.core.PathSegment objects. Each portion of the path, including matrix parameters, is placed into a unique entry in the list. Specifying false disables URI decoding.

For example the resource path box#tall/round would result in a list with three entries: box, tall, and round.

Getting the full request URI

Table 52.4, “Methods for accessing the full request URI” describes the methods that return the full request URI. You have the option of returning the request URI or the absolute path of the resource. The difference is that the request URI includes the any query parameters appended to the URI and the absolute path does not include the query parameters.

Table 52.4. Methods for accessing the full request URI

MethodDesription

URIgetRequestUri

Returns the complete request URI, including query parameters and matrix parameters, as a java.net.URI object.

UriBuildergetRequestUriBuilder

Returns the complete request URI, including query parameters and matrix parameters, as a javax.ws.rs.UriBuilder object. The UriBuilder class is useful for creating URIs for other resources implemented by the service.

URIgetAbsolutePath

Returns the complete request URI, including matrix parameters, as a java.net.URI object. The absolute path does not include query parameters.

UriBuildergetAbsolutePathBuilder

Returns the complete request URI, including matrix parameters, as a javax.ws.rs.UriBuilder object. The absolute path does not include query parameters.

For a request made using the URI http://fusesource.org/montersforhire/nightstalker?12, the getRequestUri() methods would return http://fusesource.org/montersforhire/nightstalker?12. The getAbsolutePath() method would return http://fusesource.org/montersforhire/nightstalker.

52.2.3. Getting the value of URI template variables

Overview

As described in the section called “Setting the path”, resource paths can contain variable segments that are bound to values dynamically. Often these variable path segments are used as parameters to a resource method as described in the section called “Getting data from the URI’s path”. You can, however, also access them through the URI context.

Methods for getting the path parameters

The UriInfo interface provides two methods, shown in Example 52.1, “Methods for returning path parameters from the URI context”, that return a list of the path parameters.

Example 52.1. Methods for returning path parameters from the URI context

MultivaluedMap<java.lang.String, java.lang.String>getPathParametersMultivaluedMap<java.lang.String, java.lang.String>getPathParametersbooleandecode

The getPathParameters() method that does not take any parameters automatically decodes the path parameters. If you want to disable URI decoding use getPathParameters(false).

The values are stored in the map using their template identifiers as keys. For example if the URI template for the resource is /{color}/box/{note} the returned map will have two entries with the keys color and note.

Example

Example 52.2, “Extracting path parameters from the URI context” shows code for retrieving the path parameters using the URI context.

Example 52.2. Extracting path parameters from the URI context

import javax.ws.rs.Path;
import javax.ws.rs.Get;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.MultivaluedMap;

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

  @GET
  @Path("/{type}/{size}")
  public Monster getMonster(@Context UriInfo uri)
  {
    MultivaluedMap paramMap = uri.getPathParameters();
    String type = paramMap.getFirst("type");
    String size = paramMap.getFirst("size");
  }
}