Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/
Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Using the Connection API

This topic describes using the Connection API to send a request to a remote resource using the connection infrastructure and obtain a response. For an overview of the connection infrastructure and associated topics, see Calling a remote resource.

You can find information about the protocols supplied for use with the Connection API in the Protocol reference. If you want to send email messages then you may also be interested in the additional support described in Sending an email using EmailConnection.

An overview of the Connection API

The Connection API is contained in the zero.core.connection package and has two key classes:

  • zero.core.connection.Connection
  • zero.core.connection.Connection.Response

An application uses the Connection class to build a request and send it to the named resource and is given a reference to a Connection.Response instance. It can then use the Connection.Response object to wait for and then 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 static methods, 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 Connection object, 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 using the full Connection API and the way in which the application interacts with the Connection.Response object does not depend on the approach taken when sending the request.

The remainder of this article outlines these approaches in more detail. See the Javadoc API reference for more information.

Sending requests to resources

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 four basic forms are as follows:

Connection
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)

In addition to these 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 Map of header names and List of associated values. If no request headers are required, the application may either pass an empty Map or an null value, or else use the overloaded methods that have no headers argument.
body
The body of the request. The supported body types will depend on the protocol being used but typically will include:
  • String
  • byte[]
  • InputStream
  • Reader

The meaning of request headers and the object types supported for the request body depend upon the protocol you are using. The Protocol reference contains more details. See the Javadoc API reference for more information on the methods described above.

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/repo");
        // work with response headers and body
} catch (Exception e) {
        // handle exceptions
}

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 are in fact a shorthand for the full Connection API, which may explicitly be used by applications in more advanced scenarios.

We can rewrite the example above to replace the single doGET() call with separate statements to create a new Connection object and get the associated Connection.Response object:

Connection.Response response = Connection.doGET("http://www.projectzero.org/repo");

Connection conn = new Connection("http://www.projectzero.org/repo");
Connection.Response response = conn.getResponse();

Applications using full Connection API follow the following pattern:

  1. Create a new Connection object, specifying a target resource and operation.
  2. Set up any request headers required.
  3. Set the request body, if required.
  4. Send the request and obtain a reference to a Connection.Response.

The Connection class provides two public constructors:

Connection
Connection(String resource)
Connection(String resource, Connection.Operation operation)

By default, the first form prepares a GET request but the second allows operation defined by the enumeration, Connection.Operation:

Connection.Operation
GET
HEAD
POST
PUT
DELETE

The newly created Connection object supplies a number of methods by which request headers can be set and are summarized below. Each header consists of a name (String key) and list of associated values (List<Object> values). 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 the end of the list.

Connection
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)

The application may only call these methods before the request body has been set. Any subsequent attempts to call one of these methods will result in an IllegalStateException being thrown.

For POST and PUT operations, the request body is specified using one of two methods:

Connection
void setRequestBody(Object body)
OutputStream getRequestBodyOutputStream()

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 will depend on the protocol being used but typically will include:

  • String
  • byte[]
  • InputStream
  • Reader

Alternatively, the getRequestBodyOutputStream() method allows an application to request an OutputStream in which it will 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 the request is sent (i.e. before calling getResponse()).

The application may 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 will result in an IllegalStateException being thrown.

Once the request body is completed, the application uses the getResponse() to signal that the request should be sent to the target resource and obtain a reference to the Connection.Response object.

Connection
Connection.Response getResponse()

The following example code uses the full Connection API to prepare and send a simple email message:

Connection conn = new Connection("mailto:you@projectzero.org", Connection.Operation.POST);
conn.addRequestHeader("Subject", "Hello!");
conn.addRequestHeader("From", "me@projectzero.org");
conn.setRequestBody("This is the text of the email.");
Connection.Response resp = conn.getResponse();

Note that the EmailConnection class provides additional support for sending an email using the Connection API.

The meaning of request headers and the object types supported for the request body depend upon the protocol you are using. The Protocol reference contains more details. See the Javadoc API reference for more information on the methods described above.

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 may use the methods supplied by Connection.Response to:

  • Examine any protocol-specific status code associated with the response.
  • Examine any response headers.
  • Obtain any response body.

Note: The application is given the Connection.Response reference after the request has been sent. Depending on the protocol in use, a response may 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 will block until the requested information is available.

Working with response headers

The following methods of Connection.Response allow an application to examine the headers supplied with the response:

Connection.Response
Set<String> getResponseHeaderKeys()
List<Object> getResponseHeader(String key)

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. The basic forms are summarized below:

Connection.Response
String getResponseBodyAsString()
byte[] getResponseBodyAsBytes()
Reader getResponseBodyReader()
InputStream getResponseBodyInputStream()
Object getResponseBody()

The application may only call one of the above methods, and only once, for an individual Connection.Response object. Any subsequent attempts to call one of these methods will result 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, it is recommended that applications 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 may 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
}

The meaning of request headers and the object types supported for the request body depend upon the protocol you are using. The Protocol reference contains more details. See the Javadoc API reference for more information on the methods described above.

Advanced topics

Targeting local HTTP resources

The Connection API provides a convenient method to invoke a local HTTP resource without needing to specify a full URL. This mechanism may be used when the application invokes the Connection API whilst responding to an HTTP or HTTPS request.

When specifying a resource in any call to the Connection API, the application may use the following prefixes in place of an absolute URL.

Prefix Meaning
./ Relative to current resource.
../ Relative to parent resource.
~/ Relative to the application context root.

For example, consider an application that is responding to a request against http://mydomain.com:8080/appRoot/level1/level2/level3. Using various forms of relative resource names will have the following results:

Relative URL Resolved resource
./rel1 http://mydomain.com:8080/appRoot/level1/level2/rel1
./rel1/rel2 http://mydomain.com:8080/appRoot/level1/level2/rel1/rel2
../rel1 http://mydomain.com:8080/appRoot/level1/rel1
~/rel1/rel2 http://mydomain.com:8080/appRoot/rel1/rel2

Notes:

  1. Resource names that do not begin with the above prefixes are interpreted as absolute resource names. In particular, resources starting with / are not resolved relative to the current request.
  2. Calling Connection.getResource() will always return the absolute URL for the Connection request, regardless of whether it was specified using an absolute name or relative prefix.

Sending an email

The EmailConnection API provides a specialized interface to help send a email with optional MIME attachments using the SMTP protocol. For more information, see Sending an email using the EmailConnection API.

r22 - 07 Feb 2008 - 19:48:36 - todkap
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site