Google HTTP Client for Java

Overview
Setup Instructions
Component Modules
Android
Google App Engine
HTTP Transport
JSON
Exponential Backoff
Unit Testing
Support

Pluggable HTTP Transport

The HTTP library has a fully pluggable HTTP transport layer that allows you to build on top of the low-level HTTP of your choice and optimize for the Java platform your application is running on.

Thanks to this abstraction, code written for one platform works across all supported platforms, from mobile applications such as those built for Android, to installed applications, to web applications such as those built on Google App Engine. The HTTP library provides high-level functionality that is compatible across these platforms, but at the same time takes advantage of lower-level functionality when necessary.

Choosing a low-level HTTP transport library

There are three built-in low-level HTTP transports:

  1. NetHttpTransport: based on HttpURLConnection that is found in all Java SDKs, and thus usually the simplest choice.
  2. Apache5HttpTransport: based on the popular Apache 5.x HttpClient that allows for more customization.
  3. ApacheHttpTransport: based on the popular Apache 4.x HttpClient that allows for more customization. Note that this transport implementation relies on Apache 4.x HttpCore which has reached end of life. It is recommended to use Apache5HttpTransport instead.
  4. UrlFetchTransport: based on the URL Fetch Java API in the Google App Engine SDK.

Logging

java.util.logging.Logger is used for logging HTTP request and response details, including URL, headers, and content.

Normally logging is managed using a logging.properties file. For example:

# Properties file which configures the operation of the JDK logging facility.
# The system will look for this config file to be specified as a system property:
# -Djava.util.logging.config.file=${project_loc:googleplus-simple-cmdline-sample}/logging.properties

# Set up the console handler (uncomment "level" to show more fine-grained messages)
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = CONFIG

# Set up logging of HTTP requests and responses (uncomment "level" to show)
com.google.api.client.http.level = CONFIG

The following example uses the ConsoleHandler. Another popular choice is FileHandler.

Example for enabling logging in code:

import com.google.api.client.http.HttpTransport;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public static void enableLogging() {
  Logger logger = Logger.getLogger(HttpTransport.class.getName());
  logger.setLevel(Level.CONFIG);
  logger.addHandler(new Handler() {

    @Override
    public void close() throws SecurityException {
    }

    @Override
    public void flush() {
    }

    @Override
    public void publish(LogRecord record) {
      // Default ConsoleHandler will print >= INFO to System.err.
      if (record.getLevel().intValue() < Level.INFO.intValue()) {
        System.out.println(record.getMessage());
      }
    }
  });
}

Note: When using Level.CONFIG, the value of the Authorization header is not shown. To show that also, use Level.ALL instead of Level.CONFIG.

Handling HTTP error responses

When an HTTP error response (an HTTP status code of 300 or higher) is received, HttpRequest.execute() throws an HttpResponseException. Here’s an example usage:

try {
  request.execute()
} catch (HttpResponseException e) {
  System.err.println(e.getStatusMessage());
}

If you need to intercept error responses, it may be handy to use the HttpUnsuccessfulResponseHandler. Example usage:

public static class MyInitializer implements HttpRequestInitializer, HttpUnsuccessfulResponseHandler {

  @Override
  public boolean handleResponse(
      HttpRequest request, HttpResponse response, boolean retrySupported) throws IOException {
    System.out.println(response.getStatusCode() + " " + response.getStatusMessage());
    return false;
  }

  @Override
  public void initialize(HttpRequest request) throws IOException {
    request.setUnsuccessfulResponseHandler(this);
  }
}

...

HttpRequestFactory requestFactory = transport.createRequestFactory(new MyInitializer());