title |
---|
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.
There are three built-in low-level HTTP transports:
NetHttpTransport
: based onHttpURLConnection
that is found in all Java SDKs, and thus usually the simplest choice.Apache5HttpTransport
: based on the popular Apache 5.x HttpClient that allows for more customization.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 useApache5HttpTransport
instead.UrlFetchTransport
: based on the URL Fetch Java API in the Google App Engine SDK.
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
.
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());