The Java EE 7 Tutorial
30.1 Overview of the Client API
The JAX-RS Client API provides a high-level API for accessing any REST resources, not just JAX-RS services. The Client API is defined in the javax.ws.rs.client
package.
30.1.1 Creating a Basic Client Request Using the Client API
The following steps are needed to access a REST resource using the Client API.
-
Obtain an instance of the
javax.ws.rs.client.Client
interface. -
Configure the
Client
instance with a target. -
Create a request based on the target.
-
Invoke the request.
The Client API is designed to be fluent, with method invocations chained together to configure and submit a request to a REST resource in only a few lines of code.
Client client = ClientBuilder.newClient(); String name = client.target("http://example.com/webapi/hello") .request(MediaType.TEXT_PLAIN) .get(String.class);
In this example, the client instance is first created by calling the javax.ws.rs.client.ClientBuilder.newClient
method. Then, the request is configured and invoked by chaining method calls together in one line of code. The Client.target
method sets the target based on a URI. The javax.ws.rs.client.WebTarget.request
method sets the media type for the returned entity. The javax.ws.rs.client.Invocation.Builder.get
method invokes the service using an HTTP GET
request, setting the type of the returned entity to String
.
30.1.1.1 Obtaining the Client Instance
The Client
interface defines the actions and infrastructure a REST client requires to consume a RESTful web service. Instances of Client
are obtained by calling the ClientBuilder.newClient
method.
Client client = ClientBuilder.newClient();
Use the close
method to close Client
instances after all the invocations for the target resource have been performed:
Client client = ClientBuilder.newClient(); ... client.close();
Client
instances are heavyweight objects. For performance reasons, limit the number of Client
instances in your application, as the initialization and destruction of these instances may be expensive in your runtime environment.
30.1.1.2 Setting the Client Target
The target of a client, the REST resource at a particular URI, is represented by an instance of the javax.ws.rs.client.WebTarget
interface. You obtain a WebTarget
instance by calling the Client.target
method and passing in the URI of the target REST resource.
Client client = ClientBuilder.newClient(); WebTarget myResource = client.target("http://example.com/webapi");
For complex REST resources, it may be beneficial to create several instances of WebTarget
. In the following example, a base target is used to construct several other targets that represent different services provided by a REST resource.
Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://example.com/webapi"); // WebTarget at http://example.com/webapi/read WebTarget read = base.path("read"); // WebTarget at http://example.com/webapi/write WebTarget write = base.path("write");
The WebTarget.path
method creates a new WebTarget
instance by appending the current target URI with the path that was passed in.
30.1.1.3 Setting Path Parameters in Targets
Path parameters in client requests can be specified as URI template parameters, similar to the template parameters used when defining a resource URI in a JAX-RS service. Template parameters are specified by surrounding the template variable with braces ({}
). Call the resolveTemplate
method to substitute the {username}
, and then call the queryParam
method to add another variable to pass.
WebTarget myResource = client.target("http://example.com/webapi/read") .path("{userName}") .resolveTemplate("userName", "janedoe") .queryParam("chapter", "1");// http://example.com/webapi/read/janedoe?chapter=1Response response = myResource.request(...) .get();
30.1.1.4 Invoking the Request
After setting and applying any configuration options to the target, call one of the WebTarget.request
methods to begin creating the request. This is usually accomplished by passing to WebTarget.request
the accepted media response type for the request either as a string of the MIME type or using one of the constants in javax.ws.rs.core.MediaType
. The WebTarget.request
method returns an instance of javax.ws.rs.client.Invocation.Builder
, a helper object that provides methods for preparing the client request.
Client client = ClientBuilder.newClient(); WebTarget myResource = client.target("http://example.com/webapi/read"); Invocation.Builder builder = myResource.request(MediaType.TEXT_PLAIN);
Using a MediaType
constant is equivalent to using the string defining the MIME type.
Invocation.Builder builder = myResource.request("text/plain");
After setting the media type, invoke the request by calling one of the methods of the Invocation.Builder
instance that corresponds to the type of HTTP request the target REST resource expects. These methods are:
-
get()
-
post()
-
delete()
-
put()
-
head()
-
options()
For example, if the target REST resource is for an HTTP GET request, call the Invocation.Builder.get
method. The return type should correspond to the entity returned by the target REST resource.
Client client = ClientBuilder.newClient(); WebTarget myResource = client.target("http://example.com/webapi/read"); String response = myResource.request(MediaType.TEXT_PLAIN) .get(String.class);
If the target REST resource is expecting an HTTP POST request, call the Invocation.Builder.post
method.
Client client = ClientBuilder.newClient(); StoreOrder order = new StoreOrder(...); WebTarget myResource = client.target("http://example.com/webapi/write"); TrackingNumber trackingNumber = myResource.request(MediaType.APPLICATION_XML) .post(Entity.xml(order), TrackingNumber.class);
In the preceding example, the return type is a custom class and is retrieved by setting the type in the Invocation.Builder.post(Entity<?> entity, Class<T> responseType)
method as a parameter.
If the return type is a collection, use javax.ws.rs.core.GenericType<T>
as the response type parameter, where T
is the collection type:
List<StoreOrder> orders = client.target("http://example.com/webapi/read") .path("allOrders") .request(MediaType.APPLICATION_XML) .get(new GenericType<List<StoreOrder>>() {});
This preceding example shows how methods are chained together in the Client API to simplify how requests are configured and invoked.