What Is javax.ws.rs.core.context? (Part 1)
Familiarize yourself with resource injection using the JAX-RS API. We'll cover the annotations methods you can use to pass needed information.
Join the DZone community and get the full member experience.
Join For FreeThe JAX-RS API provides a very handy mechanism to inject a range of useful resources, such as HTTP Headers, into your endpoint. The @Context annotation is an all-purpose annotation that injects instances of the following objects:
- HttpHeaders -> HTTP header parameters and values
- UriInfo -> Captures path variables and query parameters
- SecurityContext -> Provides access to security related information for a request
- ResourceContext -> Provides access to instances of resource classes
- Request -> Precondition request processing
- Application, Configuration, and Providers -> Provide information about the JAX-RS application environment
- HttpServletRequest -> Provides access to the HttpServletRequest instance
- HttpServletResponse -> Provides access to the HttpServletResponse instance
- ServletConfig -> Provides access to the ServletConfig
- ServletContext -> Provides access to the ServletContext
Let's examine each in turn with working code examples.
Inject an HttpHeaders Instance With @Context
There are two ways to obtain the value of an HTTP header parameter. If you can, use the @HeadParam annotation to mark a resource method parameter and pass it the parameter name the value of the HTTP header parameter is assigned to the String variable annotated by the @HeadParam annotation. The following code snippet retrieves the value of the user-agent parameter and assigned it to the UserAgent String.
@HeaderParam("user-agent") String userAgent
This is a great solution if you only require a few header values, but what if you want many or are not sure of the parameter name need to iterate over the headers then this solution is not good enough. Luckily the @Context annotation comes to our rescue. This annotation can inject all HTTP header parameters in one HttpHeaders object. Take a look at the code example below:
@Path("/http-headers")
public class EndpointResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllHttpHeaders(final @Context HttpHeaders httpHeaders) {
return Response.ok(httpHeaders.getRequestHeaders()).build();
}
}
In this code snippet, the @Context annotation is used to instruct the container to pass the instance of the HttpHeaders object for the current request to the getAllHttpHeaders method. The method getRequestHeaders returns a MultivaluedMap<String, String> containing the HTTP parameters and their corresponding value. This is one of many methods that provide access to HTTP header data for the current request.
The MultivaluedMap is deserialized to JSON and sent back to the client in the response body.
If you clone the code in my GitHub repository and execute the code using the Maven command:mvn clean package
it will be deployed into an IBM Liberty Profile instance. Visit the URL http://localhost:8080/rest-server/http-headers, and a JSON representation of the HTTP headers for the request will be displayed on the screen and should look something like the following:
{
"Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"],
"accept-encoding": ["gzip, deflate, br"],
"Accept-Language": ["en-US,en;q=0.8,es;q=0.6"],
"connection": ["keep-alive"],
"Content-Type": [null],
"DNT": ["1"],
"Host": ["localhost:8080"],
"Upgrade-Insecure-Requests": ["1"],
"User-Agent": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit / 537.36(KHTML, like Gecko)
Chrome / 60.0.3112.90 Safari / 537.36 "
]
}
Let’s take a look at another example that retrieves just one of the HTTP header values.
@GET
@Path("/{header-param}")
@Produces(MediaType.APPLICATION_JSON)
public Response getSpecifiedHeader(
final @PathParam("header-param") String header_param,
final @Context HttpHeaders httpHeaders) {
return Response.ok(httpHeaders.getRequestHeader(header_param)).build();
}
In this coding example, you pass the HTTP header parameter name to the resource method via a URL parameter. Then the method uses the parameter name to retrieve the value of associated HTTPHeader parameter and passes it back to the caller in JSON format.
So a called to the endpoint http://localhost:8080/rest-server/http-headers/User-Agent returns the value of the User-Agent HTTP parameter and should look something like this:
[
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/60.0.3112.90 Safari/537.36"
]
There is a handsome collection of methods in the HttpHeader class that allow you to query the parameters in the HTTP header. Here is a list of those methods. As you can see, there are some convenience methods that return the MediaType and Local.
List<String> getRequestHeader(String var1);
String getHeaderString(String var1);
MultivaluedMap<String, String> getRequestHeaders();
List<MediaType> getAcceptableMediaTypes();
List<Locale> getAcceptableLanguages();
MediaType getMediaType();
Locale getLanguage();
Map<String, Cookie> getCookies();
Date getDate();
int getLength();
The HttpHeaders instance can also be injected as an instance variable as follows:
@Path("/http-headers")
public class HttpHeaderResource {
@Context
private HttpHeaders httpHeaders;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllHttpHeaders(){
return Response.ok(httpHeaders.getRequestHeaders()).build();
}
}
Inject a UriInfo Instance With @Context
The UriInfo interface provides access to useful information about the requests URI. You can retrieve path-related details such as query parameters and path variables.
The following code snippet gets the template parameters in the URI after the resource root.
@Path("/uri-info")
public class UriInfoResource {
@GET
@Path("/{path: .*}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPathParameters(final @Context UriInfo uriInfo){
return Response.ok(uriInfo.getPathParameters()).build();
}
}
The response received after visiting the URL http://localhost:8080/rest-server/uri-info/path/to/resource is the path after the resource root uri-info.
{
"path": [ "path/to/resource" ]
}
The URI query parameters can just as easily be retrieved with a call to the method getQueryParameters(). Take a look at the code example below.
@GET
@Path("/{search}")
@Produces(MediaType.APPLICATION_JSON)
public Response getQueryParameters(final @Context UriInfo uriInfo){
return Response.ok(uriInfo.getQueryParameters()).build();
}
A call to the URL http://localhost:8080/rest-server/uri-info/search?term=JavaEE captures the search term and value:
{
"term": [ "JavaEE" ]
}
The UriInfo instance can also be injected into an instance variable like so:
@Context
private UriInfo uriInfo;
What Next?
That is all for part 1, in part 2 of What is javax.ws.rs.core.context? you will learn how to use the @Context annotation to secure a RESTful webservice and how to retrieve and use a Resource.
Code Repository
The source code for this and all my articles are in the readlearncode_articles GitHub repository.
Learn More
Online video training from Lynda.com offers an extensive range of Java EE technologies. For example, if you are just starting out then my course Learning Java Enterprise Edition is ideal. It is a full 2 hours course covering the most important APIs in the Java EE eco-system.
On completion of this course, you can dig deeper into the other Java EE APIs and learn how to build a RESTful APIs with JAX-RS, develop a chat application with WebSocket API and use JSON with Java EE’s JSON-Processing API. There are more courses in the pipeline, so why not take a look and get ready to give your Java EE career a boost.
Further Reading
I blog regularly about Java EE on readlearncode.com and have just posted a series of articles examining the JAX-RS API in more detail. These articles discuss how to handle bean validation, MediaTypes and JAX-RS, and Resource Entities, take you deeper into this essential API.
Published at DZone with permission of Alex Theedom, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments