46.3. Building the Client Invocation

Overview

After building the target URI, using the WebTarget builder class, the next step is to configure the other aspects of the request—such as HTTP headers, cookies, and so on—using the Invocation.Builder class. The final step in building the invocation is to invoke the appropriate HTTP verb (GET, POST, PUT, or DELETE) and provide a message body, if required.

Invocation.Builder class

The javax.ws.rs.client.Invocation.Builder builder class provides the part of the fluent API that enables you to build up the contents of the HTTP message and to invoke a HTTP method.

Create the invocation builder

To create an Invocation.Builder instance, invoke one of the request methods on a javax.ws.rs.client.WebTarget instance. For example:
// Java
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Invocation.Builder;
...
WebTarget books = client.target("http://example.org/bookstore/books/123");
Invocation.Builder invbuilder = books.request();

Define HTTP headers

You can add a HTTP header to the request message using the header method, as follows:
Invocation.Builder invheader = invbuilder.header("From", "fionn@example.org");

Define cookies

You can add a cookie to the request message using the cookie method, as follows:
Invocation.Builder invcookie = invbuilder.cookie("myrestclient", "123xyz");

Define properties

You can set a property in the context of this request using the property method, as follows:
Invocation.Builder invproperty = invbuilder.property("Name", "Value");

Define accepted media types, languages, or encodings

You can define accepted media types, languages, or encodings, as follows:
Invocation.Builder invmedia = invbuilder.accept("application/xml")
                                        .acceptLanguage("en-US")
                                        .acceptEncoding("gzip");

Invoke HTTP method

The process of building a REST invocation is terminated by invoking a HTTP method, which performs the HTTP invocation. The following methods (inherited from the javax.ws.rs.client.SyncInvoker base class) can be invoked:
get
post
delete
put
head
trace
options
If the specific HTTP verb you want to invoke is not on this list, you can use the generic method method to invoke any HTTP method.

Typed responses

All of the HTTP invocation methods are provided with an untyped variant and a typed variant (which takes an extra argument). If you invoke a request using the default get() method (taking no arguments), a javax.ws.rs.core.Response object is returned from the invocation. For example:
Response res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get();
It is also possible, however, to ask for the response to be returned as a specific type, using the get(Class<T>) method. For example, to invoke a request and ask for the response to be returned as a BookInfo object:
BookInfo res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get(BookInfo.class);
In order for this to work, however, you must register a suitable entity provider with the Client instance, which is capable of mapping the response format, application/xml, to the requested type. For more details about entity providers, see Section 46.4, “Parsing Requests and Responses”.

Specifying the outgoing message in post or put

For HTTP methods that include a message body in the request (such as POST or PUT), you must specify the message body as the first argument of the method. The message body must be specified as a javax.ws.rs.client.Entity object, where the Entity encapsulates the message contents and its associated media type. For example, to invoke a POST method, where the message contents are provided as a String type:
import javax.ws.rs.client.Entity;
...
Response res = client.target("http://example.org/bookstore/registerbook")
                     .request("application/xml")
                     .put(Entity.entity("Red Hat Install Guide", "text/plain"));
If necessary, the Entity.entity() constructor method will automatically map the supplied message instance to the specified media type, using the registered entity providers. It is always possible to specify the message body as a simple String type.

Delayed invocation

Instead of invoking the HTTP request right away (for example, by invoking the get() method), you have the option of creating an javax.ws.rs.client.Invocation object, which can be invoked at a later time. The Invocation object encapsulates all of the details of the pending invocation, including the HTTP method.
The following methods can be used to build an Invocation object:
buildGet
buildPost
buildDelete
buildPut
build
For example, to create a GET Invocation object and invoke it at a later time, you can use code like the following:
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Response;
...
Invocation getBookInfo = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").buildGet();
...
// Later on, in some other part of the application:
Response = getBookInfo.invoke();

Asynchronous invocation

The JAX-RS 2.0 client API supports asynchronous invocations on the client side. To make an asynchronous invocation, simply invoke the async() method in the chain of methods following request(). For example:
Future<Response> res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get();
When you make an asynchronous invocation, the returned value is a java.util.concurrent.Future object. For more details about asynchronous invocations, see Section 46.6, “Asynchronous Processing on the Client”.