Working with HTTP or HTTPS services
A common use of the Connection API is to work with REST services over HTTP or HTTPS.
The following sections contain additional information regarding the use of the Connection
API to work with HTTP and HTTPS services.
A more general description of the Connection API can be found in
Using the Connection API.
For reference information about the http and https connection protocols
and their configuration, see HTTP and HTTPS protocols.
Invoking a simple REST service
The following example uses the Connection API and zero.core.Json to
POST a simple JSON request to a REST service and deserialize the response:
try {
// Create Connection object to POST to our target resource
Connection conn = new Connection("http://localhost:8080/myService.groovy", Connection.Operation.POST);
// Set Content-Type for request body
conn.addRequestHeader("Content-Type", "text/json; charset=\"UTF-8\"");
// Set request body (requestData is a Map representing the JSON object)
conn.setRequestBody(Json.encode(requestData));
// Send request and prepare for response
Connection.Response resp = conn.getResponse();
// Check HTTP status code was 200
if ("200".equals(resp.getResponseStatus())) {
// Could check response Content-Type here, if necessary
// Get response body and deserialize JSON
Object resultData = Json.decode(resp.getResponseBodyAsString());
// resultData now contains deserialized JSON response
} else {
// Handle status code other than "200"
}
} catch (Exception e) {
// Handle exception
}
Working with Content-Type and character encodings
The Connection API and http and https protocol implementations
honor the content encoding specified by the charset parameter of the Content-Type
header when converting between character and binary data:
- When sending a
StringorReaderobject as the response body, the application should add aContent-Typerequest header with acharsetvalue indicating the encoding to use when writing the character data into the HTTP request. If nocharsetvalue is specified, the HTTP default encoding,ISO-8859-1, will be used. - When the application requests the response body using
getResponseBodyAsString()orgetResponseBodyReader()thecharsetvalue in the response content type sent by the server will be honored. If nocharsetvalue is specified, the HTTP default encoding,ISO-8859-1, will be used.
The following code sample sends a text/plain string using the UTF-8 encoding
and obtains a string contain the response. The response is decoded using the response character encoding
specified by the server:
try {
// POST a text/plain body with UTF-8 encoding
Connection conn = new Connection("http://localhost:8080/myService.groovy", Connection.Operation.POST);
conn.addRequestHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
conn.setRequestBody("This string can contain any Unicode character");
// Read response string, using response charset encoding sent by server
String responseString = conn.getResponse().getResponseBodyAsString();
} catch (Exception e) {
// Handle exception
}
Uploading files to HTTP or HTTPS services
The Connection API can be used in conjunction with an instance of the
MultipartBody class to upload a file to HTTP or HTTPS services,
using the multipart/form-data content type. This can be seen in the following example:
try {
// Open input stream for image file contents
InputStream imageStream =
Connection.doGET("file:///C:/images/uploadImage.jpeg").getResponseInputStream();
// Prepare multipart request body
MultipartBody multipartBody = new MultipartBody(MultipartBody.MULTIPART_FORM_DATA);
MultipartBody.Part filePart = reqBody.add(imageStream, "image/jpeg");
filePart.setProperty(MultipartBody.CONTENT_DISPOSITION,
"form-data; name=\"myFile\"; filename=\"myFile.jpeg\"");
// POST multipart form data to HTTP service
String statusCode = Connection.doPOST("http://localhost:8080/uploadFile.groovy",
multipartBody).getResponseStatus();
// Check HTTP statusCode to confirm successful upload
} catch (Exception e) {
// Handle exception
}
The above example uses two Connection API invocations. The first uses the GET operation
and the file protocol to open an InputStream from which the contents of an image file can be
read. The second invocation uses the POST operation of the http protocol to send the image
file to the HTTP service.
The request body for the POST is an instance of
zero.core.connection.MultipartBody that contains a single part representing the file.
The http and https protocol implementations will perform the appropriate encoding of the
request body and send a multipart MIME message to the HTTP service.
See the API reference for zero.core for more information about
the zero.core.connection.MultipartBody class.
Targeting local HTTP resources
An application can use the Connection API to invoke a local endpoint relative to the current
request path, without specifying the full URL.
This mechanism can be used when Connection API is invoked within the
context of an incomming HTTP or HTTPS request.
Relative names can be specified using any Connection API method that
sets the target resource name.
For example, an application can use a relative name when constructing a new Connection
object:
Connection conn = new Connection("./myOtherScript.groovy");
If the above example code is invoked in the request handler for
http://myApp.projectzero.org:8080/contextRoot/someFolder/myScript.groovy,
the resulting connection will target
http://myApp.projectzero.org:8080/contextRoot/someFolder/myOtherScript.groovy.
Moreover, the result of conn.getResource() will be the full target
resource name and not ./myOtherScript.groovy
The following prefixes can be used to indicate a relative target resource name:
| Prefix | Description |
|---|---|
./ |
Relative to folder containing current request handler. |
../ |
Relative to parent of folder containing current request handler. |
~/ |
Relative to the application context root. |
Any target resource name that does not begin with one of the prefixes indicated above
will be interpreted as an absolute resource name.
In particular, resources starting with / are not resolved relative to the current request.
Basic authentication and connection configuration
The http and https protocol implementations support a number of protocol
configuration parameters, such as HTTPS trust store configuration and request timeout values.
Amongst these are the userid and password protocol configuration parameters,
which can be used to automatically include a basic authentication header in the outgoing request.
The following example uses the setProtocolConfiguration() method to
set programmatically the basic authentication credentials for the request sent
to the HTTP service:
try {
// Create Connection object (default operation is GET)
Connection conn = new Connection("http://localhost:8080/myService.groovy");
// Set parameters for basic authentication
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("userid", "user1");
parameters.put("password", "password1");
conn.setProtocolConfiguration("http", parameters);
// Send request and prepare for response
Connection.Response resp = conn.getResponse();
// Work with the response
} catch (Exception e) {
// Handle exception
}
For circumstances in which it is not be desirable to hard code protocol parameters in
the application logic, the connection infrastructure enables protocol configuration to
be specified in zero.config. For example, the following connection
destination configuration specifies the basic authentication parameters for all requests
to the http://localhost:8080/myService.groovy service:
/config/connection/destinations += {
"http://localhost:8080/myService.groovy" : {
"connection" : {
"protocol" : "http",
"config" : {
"userid" : "user1",
"password" : "password1"
}
}
}
}
With the above destination configuration in place, the application can send a request to the service without hard coding the protocol configuration:
try {
// Create Connection object (default operation is GET)
Connection conn = new Connection("http://localhost:8080/myService.groovy");
// Send request and prepare for response
Connection.Response resp = conn.getResponse();
// Work with the response
} catch (Exception e) {
// Handle exception
}
Connection handlers can also set protocol configuration. For example, a connection handler
could dynamically select a userid and password value for an
outgoing request. As with specifying the configuration in the destination configuration,
using a connection handler would avoid any modification of the application logic but would
also avoid the restriction of a fixed value in zero.config.
For more information about the mechanisms available for protocol configuration,
see Configuring protocols.
For more information about the configuration of the http and https connection protocols,
including the configuration of the trust store and key store for HTTPS communications,
see HTTP and HTTPS protocols.