Using the Connection API
Use the Connection API to send a request to a remote resource using the connection infrastructure and obtain a response.
Overview
The Connection API is used to send a request to a remote resource using any protocol supported by the
connection infrastructure. The API is included in the zero.core module and has two main classes:
-
zero.core.connection.Connection -
zero.core.connection.Connection.Response
For an overview of the connection infrastructure and associated topics, see Using the connection infrastructure.
An application uses the Connection class to build and send a request to the named resource. The application is then
given a reference to a Connection.Response instance, which it can use
to wait for and examine the status and contents of the response.
The Connection class provides the application with two alternative approaches when initiating a request:
- A collection of
staticmethods, each of which set up, initiate, and send a request in a single method call. - A more flexible API in which an application creates a
Connectionobject, sets up the request, and sends it to the target resource in a series of method calls.
Using the static methods is equivalent to sending a simple request that uses the full Connection API.
The way in which the application interacts with the Connection.Response object does not depend on the approach
taken when sending the request.
- See the API reference for
zero.corefor more information about theConnectionandConnection.Responseclasses. - Information about the protocols supplied for use with the
ConnectionAPI can be found in the Protocol reference. - See Sending an e-mail using EmailConnection for more information about using the connection infrastructure to send an e-mail.
Sending requests using the static Connection API
The static methods of the Connection class provide a simple way to send REST-style requests to resources.
The following list contains the four basic forms:
-
Connection.Response doGET(String resource, Map<String, List<Object>> headers) -
Connection.Response doPUT(String resource, Map<String, List<Object>> headers, Object body) -
Connection.Response doPOST(String resource, Map<String, List<Object>> headers, Object body) -
Connection.Response doDELETE(String resource, Map<String, List<Object>> headers)
See the API reference for zero.core
for more information about these methods.
In addition to the basic forms, the Connection class has overloaded forms that differ in the way the request headers are supplied.
- resource
- The URL or destination name of the resource to be invoked.
- headers
- The headers to be sent with the request expressed as a
Mapof header names andListof associated values. If no request headers are required, the application can supply an emptyMap, anullvalue, or use the overloaded methods that have noheadersargument. - body
- The body of the request. The supported body types depend on the protocol being used but typically include:
-
String -
byte[] -
InputStream -
Reader
-
The following code extract shows a simple example in which doGET() is used send an HTTP request to retrieve a resource:
try {
Connection.Response response = Connection.doGET("http://www.projectzero.org/");
// work with response headers and body
} catch (Exception e) {
// handle exceptions
}
The meaning of request headers and the object types supported for the request body depend upon the protocol being used. See Protocol reference for more information.
Sending requests using the full Connection API
The static methods of the Connection class offer a simple way to issue requests and obtain a
Connection.Response object. These methods simplify the full Connection API, which can
be used by applications in more advanced scenarios. Applications using full Connection API typically follow
a common pattern:
- Create a new
Connectionobject, specifying a target resource and operation. - Set up any programmatic protocol configuration required by the application.
- Set up any request headers that are required.
- Set the request body, if applicable to the operation.
- Send the request and obtain a reference to a
Connection.Responseobject.
In the example below, the single doGET() call has been replaced with separate statements to create a new Connection
object and get the associated Connection.Response object.
try {
Connection conn = new Connection("http://www.projectzero.org/");
Connection.Response response = conn.send();
// work with response headers and body
} catch (Exception e) {
// handle exceptions
}
The following example uses more methods of the full Connection API to POST a string to a REST service:
try {
Connection conn = new Connection("http://someHost.projectzero.org/myService",
Connection.Operation.POST);
conn.addRequestHeader("Content-Type", "text/json; charset=\"UTF-8\"");
conn.setRequestBody("{\"name\" : \"value\"}");
Connection.Response resp = conn.send();
// work with response headers and body
} catch (Exception e) {
// handle exceptions
}
The meaning of request headers and the object types supported for the request body depend upon the protocol being use. See the Protocol reference for more information.
Creating a Connection object
The Connection class provides two public constructors:
-
Connection(String resource) -
Connection(String resource, Connection.Operation operation)
See the API reference for zero.core
for more information about these methods.
By default, the first form prepares a GET request, but the second allows the operation to be
selected from the following values:
-
Connection.Operation.GET -
Connection.Operation.HEAD -
Connection.Operation.POST -
Connection.Operation.PUT -
Connection.Operation.DELETE
Specifying protocol configuration
Many protocols support configuration parameters that can be applied to a connection request, such as time out values or authentication credentials. An application can supply these protocol configuration values for an individual request using the following method:
-
void setProtocolConfiguration(String protocol, Map<String, Object> parameters)
See the API reference for zero.core
for more information about this method.
In the following code extract, the application specifies the http protocol and a value for
the associated readTimeout configuration parameter.
Connection conn = new Connection("http://www.projectzero.org/");
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("readTimeout", 120);
conn.setProtocolConfiguration("http", parameters);
Connection.Response resp = conn.send();
The next example is similar to the previous one but a null value is given for the
protocol name. Here, the application allows the connection request processing to select the protocol
for the request. The readTimeout configuration parameter is applied to
the protocol that is selected.
Connection conn = new Connection("http://www.projectzero.org/");
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("readTimeout", 120);
conn.setProtocolConfiguration(null, parameters);
Connection.Response resp = conn.send();
In this third example, the application specifies the event protocol and an empty
set of protocol configuration parameters.
Connection conn = new Connection("myDestination");
conn.setProtocolConfiguration("event", null);
Connection.Response resp = conn.send();
Both the protocol name and configuration parameters can
be changed during connection request processing by connection handlers and destination configuration,
overriding any values specified using setProtocolConfiguration().
For more information about the mechanisms available for protocol configuration,
see Configuring protocols.
Information about the protocols supplied for use with the Connection API and their configuration parameters can be found in the
Protocol reference.
Setting request headers
A Connection object has a number of methods by which request headers can be set:
-
void setRequestHeader(String key, List<Object> values) -
List<Object> removeRequestHeader(String key) -
void addRequestHeader(String key, Object value) -
void addRequestHeaders(Map<String, List<Object>> headers)
See the API reference for zero.core
for more information about these methods.
Each header consists of a name, of type String, and a list of associated values, of type List<Object>.
The setRequestHeader() and removeRequestHeader() methods replace, or remove, all the values for the named header.
However, the addRequestHeader() and addRequestHeaders() methods do not replace any existing header values.
If the named headers are already set, these methods append the new values to the end of the list.
The application can only call these methods before the request body has been set. Any subsequent attempts to call one of these methods
results in an IllegalStateException being thrown.
Setting the request body
When using the POST or PUT operation, the request body is specified using one of two methods:
-
void setRequestBody(Object body) -
OutputStream getRequestBodyOutputStream()
See the API reference for zero.core
for more information about these methods.
The application uses the setRequestBody() method to supply the message body in a similar way to static form of
the Connection API. The supported body types depend on the protocol being used but typically include:
-
String -
byte[] -
InputStream -
Reader
Alternatively, the getRequestBodyOutputStream() method can be used to request an OutputStream in
which to write the request body. If this method is used to supply the request body, the application must flush() and
close() the request body stream before calling send() to send the request.
The application can only call one of the methods to set the request body for an individual Connection object. Any subsequent
attempts to call one of these methods results in an IllegalStateException being thrown.
Sending the request and preparing for the response
The application uses the send() method to cause the request to be sent to
the target resource and obtain a reference to the Connection.Response object.
The send() method can only be called once.
-
Connection.Response send()
- See the API reference for
zero.corefor more information about this method. - An application can also use the
getResponse()method obtain a reference to the associatedConnection.Responseobject. If the send() has not already been called, the first invocation of getResponse() will automatically call send before returning the Connection.Response object. Subsequent invocations of getResponse() return the same response object instance.
Working with Connection.Response
After using Connection to send a request to a resource, the application is given a reference to a
Connection.Response object. For protocols that supply a response to a request, an application can use the
methods supplied by Connection.Response to complete the following actions:
- Examine any protocol-specific status code associated with the response.
- Examine any response headers.
- Obtain any response body.
The application is given the Connection.Response reference after the request is sent.
Depending on the protocol in use, a response might not have been received from the resource at this time.
If the response is still in-flight when the application eventually uses the methods of Connection.Response to examine it,
the method call blocks until the required information is available.
Getting the response status
Some connection protocols include a status code with the response. The application can obtain the status code using
getResponseStatus(). The result is a string representing the protocol specific status code, or null
if none was supplied.
-
String getResponseStatus()
See the API reference for zero.core
for more information about this method.
Working with response headers
The following methods of Connection.Response allow an application to examine the headers supplied with the response:
-
Set<String> getResponseHeaderKeys() -
List<Object> getResponseHeader(String key)
See the API reference for zero.core
for more information about these methods.
Response header values are always represented as List objects, regardless of the protocol that has been used.
The following code extract extends the doGET() example to display the first value of the response Content-Type
header, if the header is present:
try {
Connection.Response response = Connection.doGET("http://www.projectzero.org/repo");
List<Object> contentType = resp.getResponseHeader("Content-Type");
if (contentType != null) {
System.out.println(contentType.get(0).toString());
}
// work with response body
} catch (Exception e) {
// handle exceptions
}
Obtaining the response body
Connection.Response provides several methods by which the application can obtain the response body,
which are summarized in the following list:
-
String getResponseBodyAsString() -
String getResponseBodyAsString(String charset) -
byte[] getResponseBodyAsBytes() -
byte[] getResponseBodyAsBytes(String charset) -
Reader getResponseBodyReader() -
Reader getResponseBodyReader(String charset) -
InputStream getResponseBodyInputStream() -
InputStream getResponseBodyInputStream(String charset) -
Object getResponseBody()
See the API reference for zero.core
for more information about these methods.
The application can call only one of the preceding methods for an individual Connection.Response object.
Any subsequent attempts to call one of these methods results in an IllegalStateException being thrown.
The getResponseBody() method gives access to the response body object returned by the protocol implementation or any
configured connection handlers. It is intended for use in advanced applications where such specific access is required.
For general scenarios, use the method that converts the body into the form most suitable for the
application. This both simplifies the logic and protects the application from implementation or configuration changes that might change
the type of the body returned by getResponseBody().
The following extension of the doGET() example uses getResponseBodyAsString() to obtain the response
body and writes it to System.out:
try {
Connection.Response response = Connection.doGET("http://www.projectzero.org/repo");
List<Object> contentType = response.getResponseHeader("Content-Type");
if (contentType != null) {
System.out.println(contentType.get(0).toString());
}
System.out.println(response.getResponseBodyAsString());
} catch (Exception e) {
// handle exceptions
}
Releasing network resources
Any network resources needed to make the connection are automatically released when the application has
finished processing the response. It is not normally necessary to call the explicit close() method of the
Connection API.
The point at which any network resources are released depends on the
application behavior and the protocol being used.
Some protocols perform all their processing and release network resources before returning the
Connection.Response to the application.
For example, the smtp and event protocols behave in this way.
The protocols which inherently provide the response body as an InputStream
often retain network resources until the response body has been read fully.
An application which obtains the response body as an InputStream or Reader
can release any network resources by calling close() on the response body.
If the application calls getResponseBodyAsString() or getResponseBodyAsBytes()
the stream is automatically closed and any network resources released.
For example, the http and ftp protocols behave in this way.
If the application or any configured connection handler fails to close a response body stream,
the connection infrastructure automatically releases any remaining network resources when
the current application request ends; during requestEnd event processing.
An application can force a connection to be closed immediately by calling the close()
method of either the Connection or Connection.Response object.
For example, an application that establishes a large number of outbound HTTP connections within a
single request can use close() to avoid holding so many outbound network resources.
Sending requests using the PHP API
The zero.php.connection module offers PHP functions to send a request to a remote resource:
-
array
connection_get(string url, array headers) -
array
connection_post(string url, array headers, string body)
- See article Zero specific PHP Function Reference for more information about these functions.
- These two PHP functions are not fully optimized for other protocols except HTTP and HTTPS, developer should use PHP Java™ bridge on Connection API in PHP.
The following code example uses the connection_get() function to make a HTTP GET method for a resource with a Cache-Control header:
<?php
$response = connection_get('http://acme.com/resources/employees', array('Cache-Control' => 'no-cache'));
// the return value is null if the request failed
if ($response != null && $response['status'] = 200) {
$content_type = $response['headers']['Content-Type'];
$response_body = $response['body'];
// ...
}
?>