Class RestClient

All Implemented Interfaces:
Closeable, AutoCloseable, HttpClient, AnnotationProvider
Direct Known Subclasses:
MockRestClient

public class RestClient extends BeanContextable implements HttpClient, Closeable
Utility class for interfacing with remote REST interfaces.

Built upon the feature-rich Apache HttpClient library, the Juneau RestClient API adds support for fluent-style REST calls and the ability to perform marshalling of POJOs to and from HTTP parts.

Example:

// Create a basic REST client with JSON support and download a bean. MyBean bean = RestClient.create() .json5() .build() .get(URI) .run() .assertStatus().asCode().is(200) .assertHeader("Content-Type").matchesSimple("application/json*") .getContent().as(MyBean.class);

Breaking apart the fluent call, we can see the classes being used:

RestClient.Builder builder = RestClient.create().json5(); RestClient client = builder.build(); RestRequest req = client.get(URI); RestResponse res = req.run(); RestResponseStatusLineAssertion statusLineAssertion = res.assertStatus(); FluentIntegerAssertion<RestResponse> codeAssertion = statusLineAssertion.asCode(); res = codeAssertion.is(200); FluentStringAssertion<RestResponse> headerAssertion = res.assertHeader("Content-Type"); res = headerAssertion.matchesSimple("application/json*"); RestResponseBody content = res.getContent(); MyBean bean = content.as(MyBean.class);

It additionally provides support for creating remote proxy interfaces using REST as the transport medium.

Example:

// Define a Remote proxy for interacting with a REST interface. @Remote(path="/petstore") public interface PetStore { @RemotePost("/pets") Pet addPet( @Content CreatePet pet, @Header("E-Tag") UUID etag, @Query("debug") boolean debug ); } // Use a RestClient with default JSON 5 support. RestClient client = RestClient.create().json5().build(); PetStore store = client.getRemote(PetStore.class, "http://localhost:10000"); CreatePet createPet = new CreatePet("Fluffy", 9.99); Pet pet = store.addPet(createPet, UUID.randomUUID(), true);

The classes are closely tied to Apache HttpClient, yet provide lots of additional functionality:

Instances of this class are built using the RestClient.Builder class which can be constructed using the RestClient.create() method as shown above.

Clients are typically created with a root URI so that relative URIs can be used when making requests. This is done using the RestClient.Builder.rootUrl(Object) method.

Example:

// Create a client where all URIs are relative to localhost. RestClient client = RestClient.create().json().rootUrl("http://localhost:5000").build(); // Use relative paths. String body = client.get("/subpath").run().getContent().asString();

The RestClient class creates RestRequest objects using the following methods:

The RestRequest class creates RestResponse objects using the following methods:

The distinction between the two methods is that complete() automatically consumes the response body and run() does not. Note that you must consume response bodies in order for HTTP connections to be freed up for reuse! The InputStreams returned by the ResponseContent object are auto-closing once they are exhausted, so it is often not necessary to explicitly close them.

The following examples show the distinction between the two calls:

// Consuming the response, so use run(). String body = client.get(URI).run().getContent().asString(); // Only interested in response status code, so use complete(). int status = client.get(URI).complete().getStatusCode();

POJO Marshalling

By default, JSON support is provided for HTTP request and response bodies. Other languages can be specified using any of the following builder methods:

Example:

// Create a basic REST client with JSON 5 support. // Typically easier to use when performing unit tests. RestClient client = RestClient.create().json5().build();

Clients can also support multiple languages:

Example:

// Create a REST client with support for multiple languages. RestClient client1 = RestClient.create().json().xml().openApi().build(); // Create a REST client with support for all supported languages. RestClient client2 = RestClient.create().universal().build();

When using clients with multiple language support, you must specify the Content-Type header on requests with bodies to specify which serializer should be selected.

// Create a REST client with support for multiple languages. RestClient client = RestClient.create().universal().build(); client .post(URI, myBean) .contentType("application/json") .complete() .assertStatus().is(200);

Languages can also be specified per-request.

// Create a REST client with no default languages supported. RestClient client = RestClient.create().build(); // Use JSON for this request. client .post(URI, myBean) .json() .complete() .assertStatus().is(200);

The RestClient.Builder class provides convenience methods for setting common serializer and parser settings.

Example:

// Create a basic REST client with JSON support. // Use single-quotes and whitespace. RestClient client = RestClient.create().json().sq().ws().build();

Other methods are also provided for specifying the serializers and parsers used for lower-level marshalling support:

HTTP parts (headers, query parameters, form data...) are serialized and parsed using the HttpPartSerializer and HttpPartParser APIs. By default, clients are configured to use OpenApiSerializer and OpenApiParser. These can be overridden using the following methods:

Request Headers

Per-client or per-request headers can be specified using the following methods:

The supplier methods are particularly useful for header values whose values may change over time (such as Authorization headers which may need to change every few minutes).

Example:

// Create a client that adds a dynamic Authorization header to every request. RestClient client = RestClient.create().header("Authorization", ()->getMyAuthToken()).build();

The HttpPartSchema API allows you to define OpenAPI schemas to POJO data structures on both requests and responses.

Example:

// Create a client that adds a header "Foo: bar|baz" to every request. RestClient client = RestClient.create() .header("Foo", AList.of("bar","baz"), T_ARRAY_PIPES) .build();

The methods with ListOperation parameters allow you to control whether new headers get appended, prepended, or replace existing headers with the same name.

Notes:
  • Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in Header or NameValuePair objects use the values returned by that bean directly.

Request Query Parameters

Per-client or per-request query parameters can be specified using the following methods:

Example:

// Create a client that adds a ?foo=bar query parameter to every request. RestClient client = RestClient.create().query("foo", "bar").build(); // Or do it on every request. String response = client.get(URI).query("foo", "bar").run().getContent().asString();

Notes:
  • Like header values, dynamic values and OpenAPI schemas are supported.
  • Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in NameValuePair objects use the values returned by that bean directly.

Request Form Data

Per-client or per-request form-data parameters can be specified using the following methods:

Notes:
  • Like header values, dynamic values and OpenAPI schemas are supported.
  • Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in NameValuePair objects use the values returned by that bean directly.

Request Body

The request body can either be passed in with the client creator method (e.g. post(uri,body)), or can be specified via the following methods:

The request body can be any of the following types:

  • Object - POJO to be converted to text using the Serializer defined on the client or request.
  • Reader - Raw contents of Reader will be serialized to remote resource.
  • InputStream - Raw contents of InputStream will be serialized to remote resource.
  • HttpResource - Raw contents will be serialized to remote resource. Additional headers and media type will be set on request.
  • HttpEntity - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
  • PartList - Converted to a URL-encoded FORM post.
  • Supplier - A supplier of anything on this list.
Notes:
  • If the serializer on the client or request is explicitly set to null, POJOs will be converted to strings using the registered part serializer as content type "text/plain. If the part serializer is also null, POJOs will be converted to strings using ClassMeta.toString(Object) which typically just calls Object.toString().

Response Status

After execution using RestRequest.run() or RestRequest.complete(), the following methods can be used to get the response status:

Example:

// Only interested in status code. int statusCode = client.get(URI).complete().getStatusCode();

Equivalent methods with mutable parameters are provided to allow access to status values without breaking fluent call chains.

Example:

// Interested in multiple values. Value<Integer> statusCode = Value.create(); Value<String> reasonPhrase = Value.create(); client.get(URI).complete().getStatusCode(statusCode).getReasonPhrase(reasonPhrase); System.err.println("statusCode="+statusCode.get()+", reasonPhrase="+reasonPhrase.get());

Notes:
  • If you are only interested in the response status and not the response body, be sure to use RestRequest.complete() instead of RestRequest.run() to make sure the response body gets automatically cleaned up. Otherwise you must consume the response yourself.

The assertion method is provided for quickly asserting status codes in fluent calls.

Example:

// Status assertion using a static value. String body = client.get(URI) .run() .assertStatus().asCode().isBetween(200,399) .getContent().asString(); // Status assertion using a predicate. String body = client.get(URI) .run() .assertStatus().asCode().is(x -> x<400) .getContent().asString();

Response Headers

Response headers are accessed through the following methods:

The RestResponse.getFirstHeader(String) and RestResponse.getLastHeader(String) methods return an empty ResponseHeader object instead ofnull. This allows it to be used more easily in fluent calls.

Example:

// See if response contains Location header. boolean hasLocationHeader = client.get(URI).complete().getLastHeader("Location").exists();

The ResponseHeader class extends from the HttpClient Header class and provides several convenience methods:

The ResponseHeader.schema(HttpPartSchema) method allows you to perform parsing of OpenAPI formats for header parts.

Example:

// Parse the header "Foo: bar|baz". List<String> fooHeader = client .get(URI) .complete() .getHeader("Foo").schema(T_ARRAY_PIPES).as(List.class, String.class);

Assertion methods are also provided for fluent-style calls:

Note how in the following example, the fluent assertion returns control to the RestResponse object after the assertion has been completed:

Example:

// Assert the response content type is any sort of JSON. String body = client.get(URI) .run() .getHeader("Content-Type").assertValue().matchesSimple("application/json*") .getContent().asString();

Response Body

The response body is accessed through the following method:

The ResponseContent class extends from the HttpClient HttpEntity class and provides several convenience methods:


Examples:

// Parse into a linked-list of strings. List<String> list1 = client .get(URI) .run() .getContent().as(LinkedList.class, String.class); // Parse into a linked-list of beans. List<MyBean> list2 = client .get(URI) .run() .getContent().as(LinkedList.class, MyBean.class); // Parse into a linked-list of linked-lists of strings. List<List<String>> list3 = client .get(URI) .run() .getContent().as(LinkedList.class, LinkedList.class, String.class); // Parse into a map of string keys/values. Map<String,String> map1 = client .get(URI) .run() .getContent().as(TreeMap.class, String.class, String.class); // Parse into a map containing string keys and values of lists containing beans. Map<String,List<MyBean>> map2 = client .get(URI) .run() .getContent().as(TreeMap.class, String.class, List.class, MyBean.class);

The response body can only be consumed once unless it has been cached into memory. In many cases, the body is automatically cached when using the assertions methods or methods such as ResponseContent.asString(). However, methods that involve reading directly from the input stream cannot be called twice. In these cases, the RestResponse.cacheContent() and ResponseContent.cache() methods are provided to cache the response body in memory so that you can perform several operations against it.

// Cache the response body so we can access it twice. InputStream inputStream = client .get(URI) .run() .cacheBody() .getContent().pipeTo(someOtherStream) .getContent().asInputStream();

Assertion methods are also provided for fluent-style calls:


Example:

// Assert that the body contains the string "Success". String body = client .get(URI) .run() .getContent().assertString().contains("Success") .getContent().asString();

Object assertions allow you to parse the response body into a POJO and then perform various tests on that resulting POJO.

Example:

// Parse bean into POJO and then validate that it was parsed correctly. MyBean bean = client.get(URI) .run() .getContent().assertObject(MyBean.class).asJson().is("{foo:'bar'}") .getContent().as(MyBean.class);

Custom Call Handlers

The RestCallHandler interface provides the ability to provide custom handling of requests.

Note that there are other ways of accomplishing this such as extending the RestClient class and overriding the run(HttpHost,HttpRequest,HttpContext) method or by defining your own HttpRequestExecutor. Using this interface is often simpler though.

Interceptors

The RestCallInterceptor API provides a quick way of intercepting and manipulating requests and responses beyond the existing HttpRequestInterceptor and HttpResponseInterceptor APIs.

Logging / Debugging

The following methods provide logging of requests and responses:

The following example shows the results of logging all requests that end with /bean.

Examples:

MyBean bean = RestClient .create() .json5() .logRequests(DetailLevel.FULL, Level.SEVERE, (req,res)->req.getUri().endsWith("/bean")) .logToConsole() .build() .post("http://localhost/bean", anotherBean) .run() .getContent().as(MyBean.class);

This produces the following console output:

=== HTTP Call (outgoing) ====================================================== === REQUEST === POST http://localhost/bean ---request headers--- Accept: application/json5 ---request entity--- Content-Type: application/json5 ---request content--- {f:1} === RESPONSE === HTTP/1.1 200 ---response headers--- Content-Type: application/json ---response content--- {f:1} === END =======================================================================",

It should be noted that if you enable request logging detail level DetailLevel.FULL, response bodies will be cached by default which may introduce a performance penalty.

Additionally, the following method is also provided for enabling debug mode:

Enabling debug mode has the following effects:

REST Proxies

One of the more powerful features of the REST client class is the ability to produce Java interface proxies against arbitrary remote REST resources.

Example:

// Define a Remote proxy for interacting with a REST interface. @Remote(path="/petstore") public interface PetStore { @RemotePost("/pets") Pet addPet( @Content CreatePet pet, @Header("E-Tag") UUID etag, @Query("debug") boolean debug ); } // Use a RestClient with default JSON 5 support. RestClient client = RestClient.create().json5().build()) PetStore store = client.getRemote(PetStore.class, "http://localhost:10000"); CreatePet createPet = new CreatePet("Fluffy", 9.99); Pet pet = store.addPet(createPet, UUID.randomUUID(), true);

The methods to retrieve remote interfaces are:

Two basic types of remote interfaces are provided:

  • @Remote-annotated interfaces. These can be defined against arbitrary external REST resources.
  • RPC-over-REST interfaces. These are Java interfaces that allow you to make method calls on server-side POJOs.

Refer to the following documentation on both flavors:



Customizing Apache HttpClient

Several methods are provided for customizing the underlying HTTP client and client builder classes:

Additionally, all methods on the HttpClientBuilder class have been extended with fluent setters.

Example:

// Create a client with customized HttpClient settings. MyBean bean = RestClient .create() .disableRedirectHandling() .connectionManager(myConnectionManager) .addInterceptorFirst(myHttpRequestInterceptor) .build();

Refer to the HTTP Client Builder API for more information.

Extending RestClient

The RestClient API has been designed to allow for the ability to be easily extended. The following example that overrides the primary run method shows how this can be done.

Example:

public class MyRestClient extends RestClient { // Must provide this constructor! public MyRestClient(RestClient.Builder builder) { super(builder); } /** Optionally override to customize builder settings before initialization. @Override protected void init(RestClient.Builder) {...} /** Optionally override to provide post-initialization (e.g. setting up SAML handshakes, etc...). @Override protected void init() {...} /** Optionally override to customize requests when they're created (e.g. add headers to each request). @Override protected RestRequest request(RestOperation) {...} /** Optionally override to implement your own call handling. @Override protected HttpResponse run(HttpHost, HttpRequest, HttpContext) {...} /** Optionally override to customize requests before they're executed. @Override protected void onCallInit(RestRequest) {...} /** Optionally override to customize responses as soon as a connection is made. @Override protected void onCallConnect(RestRequest, RestResponse) {...} /** Optionally override to perform any call cleanup. @Override protected void onCallClose(RestRequest, RestResponse) {...} } // Instantiate your client. MyRestClient client = RestClient.create().json().build(MyRestClient.class);

The RestRequest and RestResponse objects can also be extended and integrated by overriding the createRequest(URI,String,boolean) and createResponse(RestRequest,HttpResponse,Parser) methods.

Notes:
  • This class is thread safe and reusable.
See Also:
  • Constructor Details

  • Method Details

    • create

      public static RestClient.Builder create()
      Instantiates a new clean-slate RestClient.Builder object.
      Returns:
      A new RestClient.Builder object.
    • copy

      Description copied from class: Context
      Creates a builder from this context object.

      Builders are used to define new contexts (e.g. serializers, parsers) based on existing configurations.

      Overrides:
      copy in class Context
      Returns:
      A new Builder object.
    • init

      protected void init(RestClient.Builder builder)
      Perform optional initialization on builder before it is used.

      Default behavior is a no-op.

      Parameters:
      builder - The builder to initialize.
    • init

      protected void init()
      Gets called add the end of the constructor call to perform any post-initialization.
    • close

      public void close() throws IOException
      Calls Closeable.close() on the underlying CloseableHttpClient.

      It's good practice to call this method after the client is no longer used.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException - Thrown by underlying stream.
    • closeQuietly

      public void closeQuietly()
      Same as close(), but ignores any exceptions.
    • run

      protected HttpResponse run(HttpHost target, HttpRequest request, HttpContext context) throws ClientProtocolException, IOException
      Entrypoint for executing all requests and returning a response.

      Subclasses can override this method to provide specialized handling.

      The behavior of this method can also be modified by specifying a different RestCallHandler.

      See Also:
      Parameters:
      target - The target host for the request.
      Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.
      request - The request to execute.
      context - The context to use for the execution, or null to use the default context.
      Returns:
      The response to the request.
      This is always a final response, never an intermediate response with an 1xx status code.
      Whether redirects or authentication challenges will be returned or handled automatically depends on the implementation and configuration of this client.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • get

      public RestRequest get(Object uri) throws RestCallException
      Perform a GET request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • get

      Perform a GET request against the root URI.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • put

      public RestRequest put(Object uri, Object body) throws RestCallException
      Perform a PUT request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request. Can be of the following types:
      • Reader - Raw contents of Reader will be serialized to remote resource.
      • InputStream - Raw contents of InputStream will be serialized to remote resource.
      • Object - POJO to be converted to text using the Serializer registered with the RestClient.
      • HttpEntity / HttpResource - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
      • PartList - Converted to a URL-encoded FORM post.
      • Supplier - A supplier of anything on this list.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • put

      public RestRequest put(Object uri, String body, ContentType contentType) throws RestCallException
      Perform a PUT request against the specified URI using a plain text body bypassing the serializer.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
      contentType - The content type of the request.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • put

      public RestRequest put(Object uri) throws RestCallException
      Same as put(Object, Object) but don't specify the input yet.

      You must call either RestRequest.content(Object) or RestRequest.formData(String, Object) to set the contents on the result object.

      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - REST call failed.
    • post

      public RestRequest post(Object uri, Object body) throws RestCallException
      Perform a POST request against the specified URI.
      Notes:
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request. Can be of the following types:
      • Reader - Raw contents of Reader will be serialized to remote resource.
      • InputStream - Raw contents of InputStream will be serialized to remote resource.
      • Object - POJO to be converted to text using the Serializer registered with the RestClient.
      • HttpEntity / HttpResource - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
      • PartList - Converted to a URL-encoded FORM post.
      • Supplier - A supplier of anything on this list.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • post

      public RestRequest post(Object uri, String body, ContentType contentType) throws RestCallException
      Perform a POST request against the specified URI as a plain text body bypassing the serializer.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
      contentType - The content type of the request.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • post

      Same as post(Object, Object) but don't specify the input yet.

      You must call either RestRequest.content(Object) or RestRequest.formData(String, Object) to set the contents on the result object.

      Notes:
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - REST call failed.
    • delete

      Perform a DELETE request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • options

      Perform an OPTIONS request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • head

      Perform a HEAD request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • formPost

      public RestRequest formPost(Object uri, Object body) throws RestCallException
      Perform a POST request with a content type of application/x-www-form-urlencoded against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • formPost

      Same as formPost(Object, Object) but doesn't specify the input yet.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • formPostPairs

      public RestRequest formPostPairs(Object uri, String... parameters) throws RestCallException
      Perform a POST request with a content type of application/x-www-form-urlencoded against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      parameters - The parameters of the form post.
      The parameters represent name/value pairs and must be an even number of arguments.
      Parameters are converted to BasicPart objects.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • patch

      public RestRequest patch(Object uri, Object body) throws RestCallException
      Perform a PATCH request against the specified URI.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request. Can be of the following types:
      • Reader - Raw contents of Reader will be serialized to remote resource.
      • InputStream - Raw contents of InputStream will be serialized to remote resource.
      • HttpResource - Raw contents will be serialized to remote resource. Additional headers and media type will be set on request.
      • HttpEntity - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
      • Object - POJO to be converted to text using the Serializer registered with the RestClient.
      • PartList - Converted to a URL-encoded FORM post.
      • Supplier - A supplier of anything on this list.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • patch

      public RestRequest patch(Object uri, String body, ContentType contentType) throws RestCallException
      Perform a PATCH request against the specified URI as a plain text body bypassing the serializer.
      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
      contentType - The content type of the request.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • patch

      Same as patch(Object, Object) but don't specify the input yet.

      You must call RestRequest.content(Object) to set the contents on the result object.

      Parameters:
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - REST call failed.
    • callback

      public RestRequest callback(String callString) throws RestCallException
      Performs a REST call where the entire call is specified in a simple string.

      This method is useful for performing callbacks when the target of a callback is passed in on an initial request, for example to signal when a long-running process has completed.

      The call string can be any of the following formats:

      • "[method] [uri]" - e.g. "GET http://localhost/callback"
      • "[method] [uri] [payload]" - e.g. "POST http://localhost/callback some text payload"
      • "[method] [headers] [uri] [payload]" - e.g. "POST {'Content-Type':'text/json'} http://localhost/callback {'some':'json'}"

      The payload will always be sent using a simple StringEntity.

      Parameters:
      callString - The call string.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - REST call failed.
    • request

      public RestRequest request(String method, Object uri, Object body) throws RestCallException
      Perform a generic REST call.
      Parameters:
      method - The HTTP method.
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      body - The HTTP body content. Can be of the following types:
      • Reader - Raw contents of Reader will be serialized to remote resource.
      • InputStream - Raw contents of InputStream will be serialized to remote resource.
      • HttpResource - Raw contents will be serialized to remote resource. Additional headers and media type will be set on request.
      • HttpEntity - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
      • Object - POJO to be converted to text using the Serializer registered with the RestClient.
      • PartList - Converted to a URL-encoded FORM post.
      • Supplier - A supplier of anything on this list.
      This parameter is IGNORED if the method type normally does not have content.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • request

      public RestRequest request(String method, Object uri) throws RestCallException
      Perform a generic REST call.
      Parameters:
      method - The HTTP method.
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • request

      public RestRequest request(String method, Object uri, boolean hasBody) throws RestCallException
      Perform a generic REST call.

      Typically you're going to use request(String, Object) or request(String, Object, Object), but this method is provided to allow you to perform non-standard HTTP methods (e.g. HTTP FOO).

      Parameters:
      method - The method name (e.g. "GET", "OPTIONS").
      uri - The URI of the remote REST resource.
      Can be any of the following types:
      hasBody - Boolean flag indicating if the specified request has content associated with it.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • request

      Perform an arbitrary request against the specified URI.

      All requests feed through this method so it can be used to intercept request creations and make modifications (such as add headers).

      Parameters:
      op - The operation that identifies the HTTP method, URL, and optional payload.
      Returns:
      A RestRequest object that can be further tailored before executing the request and getting the response as a parsed object.
      Throws:
      RestCallException - If any authentication errors occurred.
    • createRequest

      protected RestRequest createRequest(URI uri, String method, boolean hasBody) throws RestCallException
      Creates a RestRequest object from the specified HttpRequest object.

      Subclasses can override this method to provide their own specialized RestRequest objects.

      Parameters:
      uri - The target.
      method - The HTTP method (uppercase).
      hasBody - Whether this method has a request entity.
      Returns:
      A new RestRequest object.
      Throws:
      RestCallException - If an exception or non-200 response code occurred during the connection attempt.
    • createResponse

      protected RestResponse createResponse(RestRequest request, HttpResponse httpResponse, Parser parser) throws RestCallException
      Creates a RestResponse object from the specified HttpResponse object.

      Subclasses can override this method to provide their own specialized RestResponse objects.

      Parameters:
      request - The request creating this response.
      httpResponse - The response object to wrap.
      parser - The parser to use to parse the response.
      Returns:
      A new RestResponse object.
      Throws:
      RestCallException - If an exception or non-200 response code occurred during the connection attempt.
    • getRemote

      public <T> T getRemote(Class<T> interfaceClass)
      Create a new proxy interface against a 3rd-party REST interface.

      The URI to the REST interface is based on the following values:

      • The @Remote(path) annotation on the interface (remote-path).
      • The rootUrl on the client (root-url).
      • The fully-qualified class name of the interface (class-name).

      The URI calculation is as follows:

      • remote-path - If remote path is absolute.
      • root-uri/remote-path - If remote path is relative and root-uri has been specified.
      • root-uri/class-name - If remote path is not specified.

      If the information is not available to resolve to an absolute URI, a RemoteMetadataException is thrown.

      Examples:

      package org.apache.foo; @RemoteResource(path="http://hostname/resturi/myinterface1") public interface MyInterface1 { ... } @RemoteResource(path="/myinterface2") public interface MyInterface2 { ... } public interface MyInterface3 { ... } // Resolves to "http://localhost/resturi/myinterface1" MyInterface1 interface1 = RestClient .create() .build() .getRemote(MyInterface1.class); // Resolves to "http://hostname/resturi/myinterface2" MyInterface2 interface2 = RestClient .create() .rootUrl("http://hostname/resturi") .build() .getRemote(MyInterface2.class); // Resolves to "http://hostname/resturi/org.apache.foo.MyInterface3" MyInterface3 interface3 = RestClient .create() .rootUrl("http://hostname/resturi") .build() .getRemote(MyInterface3.class);

      Notes:
      • If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying pooling client connection manager.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      Returns:
      The new proxy interface.
      Throws:
      RemoteMetadataException - If the REST URI cannot be determined based on the information given.
    • getRemote

      public <T> T getRemote(Class<T> interfaceClass, Object rootUrl)
      Same as getRemote(Class) except explicitly specifies the URI of the REST interface.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      rootUrl - The URI of the REST interface.
      Returns:
      The new proxy interface.
    • getRemote

      public <T> T getRemote(Class<T> interfaceClass, Object rootUrl, Serializer serializer, Parser parser)
      Same as getRemote(Class, Object) but allows you to override the serializer and parser used.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      rootUrl - The URI of the REST interface.
      serializer - The serializer used to serialize POJOs to the body of the HTTP request.
      parser - The parser used to parse POJOs from the body of the HTTP response.
      Returns:
      The new proxy interface.
    • getRrpcInterface

      public <T> T getRrpcInterface(Class<T> interfaceClass)
      Create a new proxy interface against an RRPC-style service.

      Remote interfaces are interfaces exposed on the server side using either the RrpcServlet or RRPC REST methods.

      The URI to the REST interface is based on the following values:

      • The @Remote(path) annotation on the interface (remote-path).
      • The rootUrl on the client (root-url).
      • The fully-qualified class name of the interface (class-name).

      The URI calculation is as follows:

      • remote-path - If remote path is absolute.
      • root-url/remote-path - If remote path is relative and root-url has been specified.
      • root-url/class-name - If remote path is not specified.

      If the information is not available to resolve to an absolute URI, a RemoteMetadataException is thrown.

      Notes:
      • If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying pooling client connection manager.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      Returns:
      The new proxy interface.
      Throws:
      RemoteMetadataException - If the REST URI cannot be determined based on the information given.
    • getRrpcInterface

      public <T> T getRrpcInterface(Class<T> interfaceClass, Object uri)
      Same as getRrpcInterface(Class) except explicitly specifies the URI of the REST interface.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      uri - The URI of the REST interface.
      Returns:
      The new proxy interface.
    • getRrpcInterface

      public <T> T getRrpcInterface(Class<T> interfaceClass, Object uri, Serializer serializer, Parser parser)
      Same as getRrpcInterface(Class, Object) but allows you to override the serializer and parser used.
      See Also:
      Type Parameters:
      T - The interface to create a proxy for.
      Parameters:
      interfaceClass - The interface to create a proxy for.
      uri - The URI of the REST interface.
      serializer - The serializer used to serialize POJOs to the body of the HTTP request.
      parser - The parser used to parse POJOs from the body of the HTTP response.
      Returns:
      The new proxy interface.
    • finalize

      protected void finalize() throws Throwable
      Overrides:
      finalize in class Object
      Throws:
      Throwable
    • log

      protected void log(Level level, Throwable t, String msg, Object... args)
      Logs a message.
      Parameters:
      level - The log level.
      t - Thrown exception. Can be null.
      msg - The message.
      args - Optional message arguments.
    • log

      protected void log(Level level, String msg, Object... args)
      Logs a message.
      Parameters:
      level - The log level.
      msg - The message with MessageFormat-style arguments.
      args - The arguments.
    • getPartSerializer

      Returns the part serializer associated with this client.
      Returns:
      The part serializer associated with this client.
    • getPartParser

      Returns the part parser associated with this client.
      Returns:
      The part parser associated with this client.
    • getPartSerializer

      Returns the part serializer instance of the specified type.
      Parameters:
      c - The part serializer class.
      Returns:
      The part serializer.
    • getPartParser

      Returns the part parser instance of the specified type.
      Parameters:
      c - The part parser class.
      Returns:
      The part parser.
    • isSkipEmptyHeaderData

      protected boolean isSkipEmptyHeaderData()
      Returns true if empty request header values should be ignored.
      Returns:
      true if empty request header values should be ignored.
    • isSkipEmptyQueryData

      protected boolean isSkipEmptyQueryData()
      Returns true if empty request query parameter values should be ignored.
      Returns:
      true if empty request query parameter values should be ignored.
    • isSkipEmptyFormData

      protected boolean isSkipEmptyFormData()
      Returns true if empty request form-data parameter values should be ignored.
      Returns:
      true if empty request form-data parameter values should be ignored.
    • createHeaderData

      Creates a mutable copy of the header data defined on this client.

      Used during the construction of RestRequest objects.

      Subclasses can override this method to provide their own builder.

      Returns:
      A new builder.
    • createQueryData

      Creates a mutable copy of the query data defined on this client.

      Used during the construction of RestRequest objects.

      Subclasses can override this method to provide their own builder.

      Returns:
      A new builder.
    • createFormData

      Creates a mutable copy of the form data defined on this client.

      Used during the construction of RestRequest objects.

      Subclasses can override this method to provide their own builder.

      Returns:
      A new builder.
    • createPathData

      Creates a mutable copy of the path data defined on this client.

      Used during the construction of RestRequest objects.

      Subclasses can override this method to provide their own builder.

      Returns:
      A new builder.
    • onCallInit

      protected void onCallInit(RestRequest req) throws RestCallException
      Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been copied from the client.

      Subclasses can override this method to intercept the request and perform special modifications.

      See Also:
      Parameters:
      req - The HTTP request.
      Throws:
      RestCallException - If any of the interceptors threw an exception.
    • onCallConnect

      protected void onCallConnect(RestRequest req, RestResponse res) throws RestCallException
      Interceptor method called immediately after an HTTP response has been received.

      Subclasses can override this method to intercept the response and perform special modifications.

      See Also:
      Parameters:
      req - The HTTP request.
      res - The HTTP response.
      Throws:
      RestCallException - If any of the interceptors threw an exception.
    • onCallClose

      protected void onCallClose(RestRequest req, RestResponse res) throws RestCallException
      Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been set on the request from the client.

      Subclasses can override this method to handle any cleanup operations.

      See Also:
      Parameters:
      req - The HTTP request.
      res - The HTTP response.
      Throws:
      RestCallException - If any of the interceptors threw an exception.
    • getParams

      Deprecated.
      Obtains the parameters for this client. These parameters will become defaults for all requests being executed with this client, and for the parameters of dependent objects in this client.
      Specified by:
      getParams in interface HttpClient
      Returns:
      The default parameters.
    • getConnectionManager

      Deprecated.
      Obtains the connection manager used by this client.
      Specified by:
      getConnectionManager in interface HttpClient
      Returns:
      The connection manager.
    • getHttpClientConnectionManager

      Returns the connection manager if one was specified in the client builder.
      Returns:
      The connection manager. May be null.
    • execute

      Executes HTTP request using the default context.
      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      request - The request to execute.
      Returns:
      The response to the request.
      This is always a final response, never an intermediate response with an 1xx status code.
      Whether redirects or authentication challenges will be returned or handled automatically depends on the implementation and configuration of this client.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      Executes HTTP request using the given context.
      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      request - The request to execute.
      context - The context to use for the execution, or null to use the default context.
      Returns:
      The response to the request.
      This is always a final response, never an intermediate response with an 1xx status code.
      Whether redirects or authentication challenges will be returned or handled automatically depends on the implementation and configuration of this client.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      Executes HTTP request using the default context.
      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      target - The target host for the request.
      Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.
      request - The request to execute.
      Returns:
      The response to the request.
      This is always a final response, never an intermediate response with an 1xx status code.
      Whether redirects or authentication challenges will be returned or handled automatically depends on the implementation and configuration of this client.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      Executes HTTP request using the given context.
      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      • The run(HttpHost,HttpRequest,HttpContext) method has been provided as a wrapper around this method. Subclasses can override these methods for handling requests with and without bodies separately.
      • The RestCallHandler interface can also be implemented to intercept this method.
      Specified by:
      execute in interface HttpClient
      Parameters:
      target - The target host for the request.
      Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.
      request - The request to execute.
      context - The context to use for the execution, or null to use the default context.
      Returns:
      The response to the request.
      This is always a final response, never an intermediate response with an 1xx status code.
      Whether redirects or authentication challenges will be returned or handled automatically depends on the implementation and configuration of this client.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException
      Executes HTTP request using the default context and processes the response using the given response handler.

      The content entity associated with the response is fully consumed and the underlying connection is released back to the connection manager automatically in all cases relieving individual ResponseHandlers from having to manage resource deallocation internally.

      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      request - The request to execute.
      responseHandler - The response handler.
      Returns:
      Object returned by response handler.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException
      Executes HTTP request using the given context and processes the response using the given response handler.

      The content entity associated with the response is fully consumed and the underlying connection is released back to the connection manager automatically in all cases relieving individual ResponseHandlers from having to manage resource deallocation internally.

      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      request - The request to execute.
      responseHandler - The response handler.
      context - The context to use for the execution, or null to use the default context.
      Returns:
      The response object as generated by the response handler.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException
      Executes HTTP request to the target using the default context and processes the response using the given response handler.

      The content entity associated with the response is fully consumed and the underlying connection is released back to the connection manager automatically in all cases relieving individual ResponseHandlers from having to manage resource deallocation internally.

      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      target - The target host for the request.
      Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.
      request - The request to execute.
      responseHandler - The response handler.
      Returns:
      The response object as generated by the response handler.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • execute

      public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException
      Executes a request using the default context and processes the response using the given response handler.

      The content entity associated with the response is fully consumed and the underlying connection is released back to the connection manager automatically in all cases relieving individual ResponseHandlers from having to manage resource deallocation internally.

      Notes:
      • This method gets passed on directly to the underlying HttpClient class.
      Specified by:
      execute in interface HttpClient
      Parameters:
      target - The target host for the request.
      Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.
      request - The request to execute.
      responseHandler - The response handler.
      context - The context to use for the execution, or null to use the default context.
      Returns:
      The response object as generated by the response handler.
      Throws:
      IOException - In case of a problem or the connection was aborted.
      ClientProtocolException - In case of an http protocol error.
    • properties

      protected JsonMap properties()
      Description copied from class: Context
      Returns the properties on this bean as a map for debugging.
      Overrides:
      properties in class BeanContextable
      Returns:
      The properties on this bean as a map for debugging.