JAX-RS Core Part II

Let's continue our coverage of JAX-RS fundamentals. In this lesson, we'll look how JAX-RS makes it possible to easily extract information from incoming client HTTP request. We specifically focus on

  • HTTP URI parameters: path, query & matrix

  • Other parts of a HTTP request: cookies, headers etc.

We use the word injection simply because it's the JAX-RS container, which does the heavy lifting of passing on the values of the individual components to our code (based on the metadata/annotations discussed in this chapter) - inversion on control at its best

HTTP URI parameter injection

A HTTP request URI contains: query, path and matrix parameters

  • The JAX-RS API has standard annotations in order to easily inject the values of these URI parameters into your business logic

  • These annotations are applicable on methods, instance variables and method parameters

JAX-RS annotation

Description

Example

@java.ws.rs.QueryParam

Injects HTTP query parameters

/talks?id=CON1234

@java.ws.rs.PathParam

Injects template parameters in URI or path segements

/users/JDOE

@java.ws.rs.MatrixParam

Injects matrix parameters

/talks/devoxx;year=2015/jvm

//Parameter injection in action
@Path("/conferences")
public class ConferencesResource {
@GET
@Path("{category}")
public Response get(@PathParam("category") String category,
@QueryParam("rating") int rating){
ConferenceSearchCriteria criteria = buildCriteria(category, rating);
Conferences result = search(criteria);
return Response.ok(result).build();
}
}

Here is how this works

  • A HTTP GET request on the URI /conferences/bigdata?rating=5

  • JAX-RS container extracts the value 'bigdata' from the 'category' path parameter and injects in into your method parameter

  • JAX-RS container also extracts the value '5' from the 'rating' query parameter and injects in into the method parameter

  • The business logic in the method is executed, a search is performed and the applicable conferences are returned to the caller

Injecting other HTTP request components

In addition components outlined above, a HTTP request has other vital attributes which your application code might need to be aware of e.g. header variables, cookies, form data (during a POST operation) etc

These too are applicable on methods, instance variables and method parameters

JAX-RS annotation

Description

@java.ws.rs.HeaderParam

Helps capture individual HTTP headers

@java.ws.rs.CookieParam

Extracts the specified Cookie in the HTTP request

@java.ws.rs.FormParam

Pulls values of individual attributes posted via HTML forms

@java.ws.rs.BeanParam

A convenience annotation which helps inject an instance of a class whose fields or methods are annotated with previously mentioned injection specific annotations. Prevents having to use multiple fields or method parameters to capture multiple HTTP attributes of a particular request

//Injecting other stuff
@Path("{user}/approvals")
public class UserApprovalsResource {
@HeaderParam("token")
private Token authT;
@CookieParam("temp")
private String temp;
@GET
public Response all(@PathParam("user") String user){
checkToken(user, authT);
Logger.info("Cookie 'temp' -> "+ temp);
Approvals result = searchApprovalsForUser(user);
return Response.ok(result).build();
}
}

The @BeanParam annotation was introduced in JAX-RS 2.0. Let's look at why it's so useful

@BeanParam in action

JAX-RS allows you to encapsulate the information injected via the above mentioned annotations (@PathParam, @QueryParam, @MatrixParam, @FormParam, @HeaderParam and @CookieParam) within simple POJOs.

Here is an example

//@BeanParam in action (I)
public class Pagination {
@QueryParam("s")
private int start;
@QueryParam("e")
private int end;
//getters . . .
}
//@BeanParam in action (II)
@Path("/conferences")
public class ConferencesResource {
//triggered by HTTP GET to /conferences?s=1&e=25
@GET
public Response all(@BeanParam Pagination pgSize){
Conferences result = searchAllWithPagination(pgSize);
//send back 25 results
return Response.ok(result).build();
}
}

Modus operandi

  • Annotate the fields of the model (POJO) class with the @Param annotations

  • Inject custom value/domain/model objects into fields or method parameters of JAX-RS resource classes using @BeanParam

  • JAX-RS provider automatically constructs and injects an instance of your domain object which you can now use within your methods

@BeanParam is applicable to method, parameter or field