diff --git a/.gitignore b/.gitignore index cb264df74..b7c3b9ec7 100644 --- a/.gitignore +++ b/.gitignore @@ -27,8 +27,5 @@ nosetests.xml **/.classpath **/.checkstyle -# Built documentation -docs/ - # Python utilities *.pyc diff --git a/README.md b/README.md index b69b82a60..5b5d4f1c2 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,8 @@ might result, and you are not guaranteed a compilation error. ## Documentation -- [Developer's Guide](https://github.com/googleapis/google-http-java-client/wiki) -- [Setup Instructions](https://github.com/googleapis/google-http-java-client/wiki/Setup-Instructions) +- [Developer's Guide](https://googleapis.github.io/google-http-java-client/) +- [Setup Instructions](https://googleapis.github.io/google-http-java-client/setup.html) - [JavaDoc](https://googleapis.dev/java/google-http-client/latest/) - [Release Notes](https://github.com/googleapis/google-http-java-client/releases) - [Support (Questions, Bugs)](https://developers.google.com/api-client-library/java/google-http-java-client/support) diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 000000000..0c830d027 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,2 @@ +theme: jekyll-theme-dinky +title: Google HTTP Client for Java diff --git a/docs/_data/navigation.yml b/docs/_data/navigation.yml new file mode 100644 index 000000000..f2d85a0d1 --- /dev/null +++ b/docs/_data/navigation.yml @@ -0,0 +1,17 @@ +toc: + - page: Overview + url: index.html + - page: Setup Instructions + url: setup.html + - page: Component Modules + url: component-modules.html + - page: Android + url: android.html + - page: Google App Engine + url: google-app-engine.html + - page: JSON + url: json.html + - page: Exponential Backoff + url: exponential-backoff.html + - page: Unit Testing + url: unit-testing.html \ No newline at end of file diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 000000000..b3e7d30e6 --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,54 @@ + + + + + + +{% seo %} + + + + + + +
+
+

{{ site.title | default: site.github.repository_name }}

+ + {% for entry in site.data.navigation.toc %} + {{ entry.page }}
+ {% endfor %} +
+ + +
+ +
+ {{ content }} +
+ + +
+ + {% if site.google_analytics %} + + {% endif %} + + \ No newline at end of file diff --git a/docs/android.md b/docs/android.md new file mode 100644 index 000000000..35a607e13 --- /dev/null +++ b/docs/android.md @@ -0,0 +1,101 @@ +--- +title: Using the Google HTTP Client Library for Java on Android +--- + +# Using the Google HTTP Client Library for Java on Android + +If you are developing for Android and the Google API you want to use is included in the +[Google Play Services library](https://developer.android.com/google/play-services/index.html), use +that library for the best performance and experience. If the Google API you want to use with Android +is not part of the Google Play Services library, you can use the Google HTTP Client Library for +Java, which supports Android 1.5 (or higher), and which is described here. + +## Beta + +Android support for the Google HTTP Client Library for Java is `@Beta`. + +## Installation + +Follow the download instructions on the [setup][setup] page, and pay special attention to the +Android instructions for [ProGuard][proguard]. Using ProGuard or a similar tool to remove unused +code and compress it is critical for minimizing application size. For example, for the +[tasks-android-sample][tasks-android-sample], ProGuard reduces the application size ~88%, from +777KB to 93KB. + +Note that ProGuard only runs when preparing your application for release; it does not run when +preparing it for debugging, to make it easier to develop. However, be sure to test your application +in release mode, because if ProGuard is misconfigured it can cause problems that are sometimes a +challenge to debug. + +**Warning:** For Android, you MUST place the jar files in a directory named "libs" so that the APK +packager can find them. Otherwise, you will get a `NoClassDefFoundError` error at runtime. + +## Data models + +### JSON + +You have a choice of three [pluggable streaming JSON libraries][json]. Options include +[`JacksonFactory`][jackson-factory] for maximum efficiency, or +[`AndroidJsonFactory`][android-json-factory] for the smallest application size on Honeycomb +(SDK 3.0) or higher. + +### XML (`@Beta`) + +The [XML data model][xml] (`@Beta`) is optimized for efficient memory usage that minimizes parsing +and serialization time. Only the fields you need are actually parsed when processing an XML +response. + +Android already has an efficient, native, built-in XML full parser implementation, so no separate +library is needed or advised. + +## Authentication + +The best practice on Android (since the 2.1 SDK) is to use the [`AccountManager`][account-manager] +class (@Beta) for centralized identity management and credential token storage. We recommend against +using your own solution for storing user identities and credentials. + +For details about using the AccountManager with the HTTP service that you need, read the +documentation for that service. + +## HTTP transport + +If your application is targeted at Android 2.3 (Gingerbread) or higher, use the +[`NetHttpTransport`][net-http-transport] class. This class isbased on `HttpURLConnection`, which is +built into the Android SDK and is found in all Java SDKs. + +In prior Android SDKs, however, the implementation of `HttpURLConnection` was buggy, and the Apache +HTTP client was preferred. For those SDKs, use the [`ApacheHttpTransport`][apache-http-transport] +class. + +If your Android application needs to work with all Android SDKs, call +[`AndroidHttp.newCompatibleTransport()`][android-transport] (@Beta), and it will decide which of the +two HTTP transport classes to use, based on the Android SDK level. + +## Logging + +To enable logging of HTTP requests and responses, including URL, headers, and content: + +```java +Logger.getLogger(HttpTransport.class.getName()).setLevel(Level.CONFIG); +``` + +When you use `Level.CONFIG`, the value of the Authorization header is not shown. To show the +Authorization header, use `Level.ALL`. + +Furthermore, you must enable logging on your device as follows: + +```java +adb shell setprop log.tag.HttpTransport DEBUG +``` + +[setup]: https://googleapis.github.io/google-http-java-client/setup.html +[proguard]: https://googleapis.github.io/google-http-java-client/setup.html#proguard +[tasks-android-sample]: https://github.com/google/google-api-java-client-samples/tree/master/tasks-android-sample +[json]: https://googleapis.github.io/google-http-java-client/json.html +[jackson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/jackson2/JacksonFactory.html +[android-json-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/android/json/AndroidJsonFactory.html +[xml]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/xml/package-summary.html +[account-manager]: http://developer.android.com/reference/android/accounts/AccountManager.html +[net-http-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/javanet/NetHttpTransport.html +[apache-http-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/apache/ApacheHttpTransport.html +[android-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/android/http/AndroidHttp.html#newCompatibleTransport-- \ No newline at end of file diff --git a/docs/component-modules.md b/docs/component-modules.md new file mode 100644 index 000000000..1f9273d76 --- /dev/null +++ b/docs/component-modules.md @@ -0,0 +1,52 @@ +--- +title: Component Modules +--- + +# Component Modules + +This libraries is composed of several modules: + +## google-http-client + +Google HTTP Client Library for Java (google-http-client) is designed to be compatible with all +supported Java platforms, including Android. + +## google-http-client-android + +Android extensions to the Google HTTP Client Library for Java (`google-http-client-android`) support +Java Google Android (only for SDK >= 2.1) applications. This module depends on `google-http-client`. + +## google-http-client-apache-v2 + +Apache extension to the Google HTTP Client Library for Java (`google-http-client-apache-v2`) that +contains an implementation of `HttpTransport` based on the Apache HTTP Client. This module depends +on `google-http-client`. + +## google-http-client-appengine + +Google App Engine extensions to the Google HTTP Client Library for Java +(`google-http-client-appengine`) support Java Google App Engine applications. This module depends on +`google-http-client`. + +## google-http-client-gson + +GSON extension to the Google HTTP Client Library for Java (`google-http-client-gson`) that contains +an implementation of `JsonFactory` based on the GSON API. This module depends on google-http-client. + +## google-http-client-jackson2 + +Jackson2 extension to the Google HTTP Client Library for Java (`google-http-client-jackson2`) that +contains an implementation of `JsonFactory` based on the Jackson2 API. This module depends on +`google-http-client`. + +## google-http-client-protobuf + +[Protocol buffer][protobuf] extensions to theGoogle HTTP Client Library for Java +(`google-http-client-protobuf`) support protobuf data format. This module depends on `google-http-client`. + +## google-http-client-xml + +XML extensions to the Google HTTP Client Library for Java (`google-http-client-xml`) support the XML +data format. This module depends on `google-http-client`. + +[protobuf]: https://developers.google.com/protocol-buffers/docs/overview \ No newline at end of file diff --git a/docs/exponential-backoff.md b/docs/exponential-backoff.md new file mode 100644 index 000000000..b7732e19e --- /dev/null +++ b/docs/exponential-backoff.md @@ -0,0 +1,78 @@ +--- +title: Exponential Backoff +--- + +# Exponential Backoff + +Exponential backoff is an algorithm that retries requests to the server based on certain status +codes in the server response. The retries exponentially increase the waiting time up to a certain +threshold. The idea is that if the server is down temporarily, it is not overwhelmed with requests +hitting at the same time when it comes back up. + +The exponential backoff feature of the Google HTTP Client Library for Java provides an easy way to +retry on transient failures: + +* Provide an instance of [`HttpUnsuccessfulResponseHandler`][http-unsuccessful-response-handler] to +the HTTP request in question. +* Use the library's [`HttpBackOffUnsuccessfulResponseHandler`][http-backoff-handler] implementation +to handle abnormal HTTP responses with some kind of [`BackOff`][backoff] policy. +* Use [`ExponentialBackOff`][exponential-backoff] for this backoff policy. + +Backoff is turned off by default in [`HttpRequest`][http-request]. The examples below demonstrate +how to turn it on. + +## Examples + +To set [`HttpRequest`][http-request] to use +[`HttpBackOffUnsuccessfulResponseHandler`][http-backoff-handler] with default values: + +```java +HttpRequest request = ... +request.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(new ExponentialBackOff())); +// HttpBackOffUnsuccessfulResponseHandler is designed to work with only one HttpRequest at a time. +// As a result, you MUST create a new instance of HttpBackOffUnsuccessfulResponseHandler with a new +// instance of BackOff for each instance of HttpRequest. +HttpResponse = request.execute(); +``` + +To alter the detailed parameters of [`ExponentialBackOff`][exponential-backoff], use its +[`Builder`][exponential-backoff-builder] methods: + +```java +ExponentialBackOff backoff = new ExponentialBackOff.Builder() + .setInitialIntervalMillis(500) + .setMaxElapsedTimeMillis(900000) + .setMaxIntervalMillis(6000) + .setMultiplier(1.5) + .setRandomizationFactor(0.5) + .build(); +request.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff)); +``` + +To create your own implementation of [`BackOff`][backoff]: + +```java +class CustomBackOff implements BackOff { + + @Override + public long nextBackOffMillis() throws IOException { + ... + } + + @Override + public void reset() throws IOException { + ... + } +} + +request.setUnsuccessfulResponseHandler( + new HttpBackOffUnsuccessfulResponseHandler(new CustomBackOff())); +``` + + +[http-unsuccessful-response-handler]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpUnsuccessfulResponseHandler.html +[http-backoff-handler]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpBackOffUnsuccessfulResponseHandler.html +[backoff]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/BackOff.html +[exponential-backoff]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/ExponentialBackOff.html +[http-request]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpRequest.html +[exponential-backoff-builder]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/ExponentialBackOff.Builder.html \ No newline at end of file diff --git a/docs/google-app-engine.md b/docs/google-app-engine.md new file mode 100644 index 000000000..ccd83e910 --- /dev/null +++ b/docs/google-app-engine.md @@ -0,0 +1,44 @@ +--- +title: Using the Google HTTP Client Library for Java on Google App Engine +--- + +# Using the Google HTTP Client Library for Java on Google App Engine + +Google App Engine is one of the supported Java environments for the Google HTTP Client Library for Java. + +## Data models + +### JSON + +The [JSON data model][json-package] is optimized for efficient memory usage that minimizes parsing +and serialization time. Only the fields you need are actually parsed when processing a JSON +response. + +For your JSON parser, we recommend [`JacksonFactory`][jackson-factory], which is based on the +popular Jackson library. It is considered the fastest in terms of parsing/serialization. You can +also use [`GsonFactory'][gson-factory], which is based on the [Google GSON][gson] library. It is a +lighter-weight option (smaller size) that is fairly fast, but it is not quite as fast as Jackson. + +### XML (@Beta) + +The [XML datamodel][xml-package] (`@Beta`) is optimized for efficient memory usage that minimizes +parsing and serialization time. Only the fields you need are actually parsed when processing an XML +response. + +## HTTP transport + +If you have configured Google App Engine to use [`urlfetch` as the stream handler][url-fetch], then +you will use the [`UrlFetchTransport`][url-fetch-transport] provided by +`google-http-client-appengine`. + +If you are not using `urlfetch`, then you can use any of the provided +[HttpTransport][http-transport] adapters. + +[json-package]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/package-summary.html +[jackson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/jackson2/JacksonFactory.html +[gson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/gson/GsonFactory.html +[gson]: https://github.com/google/gson +[xml-package]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/xml/package-summary.html +[url-fetch]: https://cloud.google.com/appengine/docs/standard/java/issue-requests#using_urlfetch_in_a_java_8_app +[url-fetch-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/appengine/http/UrlFetchTransport.html +[http-transport]: https://googleapis.github.io/google-http-java-client/http-transport.html \ No newline at end of file diff --git a/docs/http-transport.md b/docs/http-transport.md new file mode 100644 index 000000000..ab5b50bd8 --- /dev/null +++ b/docs/http-transport.md @@ -0,0 +1,136 @@ +--- +title: Pluggable HTTP Transport +--- + +# 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`][net-http-transport]: based on [`HttpURLConnection`][http-url-connection] +that is found in all Java SDKs, and thus usually the simplest choice. +1. [`ApacheHttpTransport`][apache-http-transport]: based on the popular +[Apache HttpClient][apache-http-client] that allows for more customization. +1. [`UrlFetchTransport`][url-fetch-transport]: based on the [URL Fetch Java API][url-fetch] in the +Google App Engine SDK. + +## Logging + +[`java.util.logging.Logger`][logger] is used for logging HTTP request and response details, +including URL, headers, and content. + +Normally logging is managed using a [`logging.properties`][logging-properties] file. For example: + +```properties +# 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`][console-handler]. Another popular choice is +[`FileHandler`][file-handler]. + +Example for enabling logging in code: + +```java +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()`][request-execute] throws an [`HttpResponseException`][response-exeception]. +Here's an example usage: + +```java +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`][http-unsuccessful-response-handler]. Example usage: + +```java +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()); +``` + +[net-http-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/javanet/NetHttpTransport.html +[http-url-connection]: http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html +[apache-http-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/apache/v2/ApacheHttpTransport.html +[apache-http-client]: http://hc.apache.org/httpcomponents-client-ga/index.html +[url=fetch-transport]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/appengine/http/UrlFetchTransport.html +[url-fetch]: https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/urlfetch/package-summary +[logger]: https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html +[logging-properties]: https://github.com/google/google-http-java-client/blob/master/samples/googleplus-simple-cmdline-sample/logging.properties +[console-handler]: https://docs.oracle.com/javase/7/docs/api/java/util/logging/ConsoleHandler.html +[file-handler]: https://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html +[request-execute]: https://googleapis.dev/java/google-http-client/latest/com/google/api/client/http/HttpRequest.html#execute-- +[response-exception]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpResponseException.html +[http-unsuccessful-response-handler]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpUnsuccessfulResponseHandler.html \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..5eb9ff04b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,49 @@ +--- +title: Overview +--- + +# Overview + +## Description + +Written by Google, the Google HTTP Client Library for Java is a flexible, efficient, and powerful +Java library for accessing any resource on the web via HTTP. The library has the following +features: + +- Pluggable HTTP transport abstraction that allows you to use any low-level library such as +`java.net.HttpURLConnection`, Apache HTTP Client, or URL Fetch on Google App Engine. +- Efficient JSON and XML data models for parsing and serialization of HTTP response and request +content. The JSON and XML libraries are also fully pluggable, and they include support for +[Jackson](https://github.com/FasterXML/jackson) and Android's GSON libraries for JSON. + +The library supports the following Java environments: + +- Java 7 (or higher) +- Android 4.0 (Ice Cream Sandwich) (or higher) +- Google App Engine + +The following related projects are built on the Google HTTP Client Library for Java: + +- [Google OAuth Client Library for Java][google-oauth-client], for the OAuth 2.0 and OAuth 1.0a +authorization standards. +- [Google APIs Client Library for Java][google-api-client], for access to Google APIs. + +This is an open-source library, and [contributions][contributions] are welcome. + +## Beta Features + +Features marked with the `@Beta` annotation at the class or method level are subject to change. They +might be modified in any way, or even removed, in any major release. You should not use beta +features if your code is a library itself (that is, if your code is used on the `CLASSPATH` of users +outside your own control). + +## Deprecated Features + +Deprecated non-beta features will be removed eighteen months after the release in which they are +first deprecated. You must fix your usages before this time. If you don't, any type of breakage +might result, and you are not guaranteed a compilation error. + +[google-oauth-client]: https://github.com/googleapis/google-oauth-java-client +[google-api-client]: https://github.com/googleapis/google-api-java-client +[contributions]: CONTRIBUTING.md + diff --git a/docs/json.md b/docs/json.md new file mode 100644 index 000000000..491d73449 --- /dev/null +++ b/docs/json.md @@ -0,0 +1,276 @@ +--- +title: JSON +--- + +# JSON + +## Pluggable streaming library + +A fully pluggable JSON streaming library abstraction allows you to take advantage of the native +platform's built-in JSON library support (for example the JSON library that is built into Android +Honeycomb). The streaming library enables you to write optimized code for efficient memory usage +that minimizes parsing and serialization time. + +A big advantage of this JSON library is that the choice of low-level streaming library is fully +pluggable. There are three built-in choices, all of which extend [`JsonFactory`][json-factory]. You +can easily plug in your own implementation. + +* [`JacksonFactory`][jackson-factory]: Based on the popular [Jackson][jackson] library, which is +considered the fastest in terms of parsing/serialization speed. Our JSON library provides +`JsonFactory` implementations based on Jackson 2. +* [`GsonFactory`][gson-factory]: Based on the [Google GSON][gson] library, which is a lighter-weight +option (small size) that is also fairly fast, though not as fast as Jackson. +* [`AndroidJsonFactory`][android-json-factory] (`@Beta`): Based on the JSON library built into +Android Honeycomb (SDK 3.0) and higher, and that is identical to the Google GSON library. + +## User-defined JSON data models + +User-defined JSON data models allow you to define Plain Old Java Objects (POJOs) and define how the +library parses and serializes them to and from JSON. The code snippets below are part of a more +complete example, [googleplus-simple-cmdline-sample][google-plus-sample], which demonstrates these +concepts. + +### Example + +The following JSON snippet shows the relevant fields of a typical Google+ activity feed: + +```json +{ + "items": [ + { + "id": "z13lwnljpxjgt5wn222hcvzimtebslkul", + "url": "https://plus.google.com/116899029375914044550/posts/HYNhBAMeA7U", + "object": { + "content": "\u003cb\u003eWho will take the title of 2011 Angry Birds College Champ?\u003c/b\u003e\u003cbr /\u003e\u003cbr /\u003e\u003cbr /\u003eIt's the 2nd anniversary of Angry Birds this Sunday, December 11, and to celebrate this break-out game we're having an intercollegiate angry birds challenge for students to compete for the title of 2011 Angry Birds College Champion. Add \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/105912662528057048457\" class=\"proflink\" oid=\"105912662528057048457\"\u003eAngry Birds College Challenge\u003c/a\u003e\u003c/span\u003e to learn more. Good luck, and have fun!", + "plusoners": { + "totalItems": 27 + } + } + }, + { + "id": "z13rtboyqt2sit45o04cdp3jxuf5cz2a3e4", + "url": "https://plus.google.com/116899029375914044550/posts/X8W8m9Hk5rE", + "object": { + "content": "CNN Heroes shines a spotlight on everyday people changing the world. Hear the top ten heroes' inspiring stories by tuning in to the CNN broadcast of "CNN Heroes: An All-Star Tribute" on Sunday, December 11, at 8pm ET/5 pm PT with host \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/106168900754103197479\" class=\"proflink\" oid=\"106168900754103197479\"\u003eAnderson Cooper 360\u003c/a\u003e\u003c/span\u003e, and donate to their causes online in a few simple steps with Google Wallet (formerly known as Google Checkout): \u003ca href=\"http://www.google.com/landing/cnnheroes/2011/\" \u003ehttp://www.google.com/landing/cnnheroes/2011/\u003c/a\u003e.", + "plusoners": { + "totalItems": 21 + } + } + }, + { + "id": "z13wtpwpqvihhzeys04cdp3jxuf5cz2a3e4", + "url": "https://plus.google.com/116899029375914044550/posts/dBnaybdLgzU", + "object": { + "content": "Today we hosted one of our Big Tent events in The Hague. \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/104233435224873922474\" class=\"proflink\" oid=\"104233435224873922474\"\u003eEric Schmidt\u003c/a\u003e\u003c/span\u003e, Dutch Foreign Minister Uri Rosenthal, U.S. Secretary of State Hillary Clinton and many others came together to discuss free expression and the Internet. The Hague is our third Big Tent, a place where we bring together various viewpoints to discuss essential topics to the future of the Internet. Read more on the Official Google Blog here: \u003ca href=\"http://goo.gl/d9cSe\" \u003ehttp://goo.gl/d9cSe\u003c/a\u003e, and watch the video below for highlights from the day.", + "plusoners": { + "totalItems": 76 + } + } + } + ] +} +``` + +Here's one possible way to design the Java data classes to represent this: + +```java +/** Feed of Google+ activities. */ +public static class ActivityFeed { + + /** List of Google+ activities. */ + @Key("items") + private List activities; + + public List getActivities() { + return activities; + } +} + +/** Google+ activity. */ +public static class Activity extends GenericJson { + + /** Activity URL. */ + @Key + private String url; + + public String getUrl() { + return url; + } + + /** Activity object. */ + @Key("object") + private ActivityObject activityObject; + + public ActivityObject getActivityObject() { + return activityObject; + } +} + +/** Google+ activity object. */ +public static class ActivityObject { + + /** HTML-formatted content. */ + @Key + private String content; + + public String getContent() { + return content; + } + + /** People who +1'd this activity. */ + @Key + private PlusOners plusoners; + + public PlusOners getPlusOners() { + return plusoners; + } +} + +/** People who +1'd an activity. */ +public static class PlusOners { + + /** Total number of people who +1'd this activity. */ + @Key + private long totalItems; + + public long getTotalItems() { + return totalItems; + } +} +``` + +A fully supported [HTTP JSON parser][json-parser] makes it easy to parse HTTP responses to objects +of these user defined classes: + +```java +private static void parseResponse(HttpResponse response) throws IOException { + ActivityFeed feed = response.parseAs(ActivityFeed.class); + if (feed.getActivities().isEmpty()) { + System.out.println("No activities found."); + } else { + for (Activity activity : feed.getActivities()) { + System.out.println(); + System.out.println("-----------------------------------------------"); + System.out.println("HTML Content: " + activity.getActivityObject().getContent()); + System.out.println("+1's: " + activity.getActivityObject().getPlusOners().getTotalItems()); + System.out.println("URL: " + activity.getUrl()); + System.out.println("ID: " + activity.get("id")); + } + } +} +``` + +### Key annotation + +Use the [`@Key`][key-annotation] annotation to indicate fields that need to be parsed from or +serialized to JSON. By default, the `@Key` annotation uses the Java field name as the JSON key. To +override this, specify the value of the `@Key` annotation. + +Fields that don't have the `@Key` annotation are considered internal data and are not parsed from or +serialized to JSON. + +### Visibility + +Visibility of the fields does not matter, nor does the existence of the getter or setter methods. So +for example, the following alternative representation for `PlusOners` would work in the example +given above: + +```java +/** People who +1'd an activity. */ +public static class AlternativePlusOnersWithPublicField { + + /** Total number of people who +1'd this activity. */ + @Key + public long totalItems; +} +``` + +### GenericJson + +Normally only the fields you declare are parsed when a JSON response is parsed. The actual Google+ +activity feed response contains a lot of content that we are not using in our example. The JSON +parser skips that other content when parsing the response from Google+. + +To retain the other content, declare your class to extend [`GenericJson`][generic-json]. Notice that +`GenericJson` implements [`Map`][map], so we can use the `get` and `put` methods to set JSON +content. See [`googleplus-simple-cmdline-sample`][google-plus-sample] for an example of how it was +used in the `Activity` class above. + +### Map + +The JSON library supports any implementation of `Map`, which works similarly to `GenericJson`. The +downside, of course, is that you lose the static type information for the fields. + +### JSON null + +One advantage of this JSON library is its ability to support JSON nulls and distinguish them from +undeclared JSON keys. Although JSON nulls are relatively rare, when they do occur they often cause +confusion. + +Google+ doesn't use JSON null values, so the following example uses fictitious JSON data to +illustrate what can happen: + +```json +{ + "items": [ + { + "id": "1", + "value": "some value" + }, + { + "id": "2", + "value": null + } + { + "id": "3" + } + ] +} +``` + +We might represent each item as follows: + +```java +public class Item { + @Key + public String id; + @Key + public String value; +} +``` + +For items 2 and 3, what should be in the value field? The problem is that there is no obvious way in +Java to distinguish between a JSON key that is undeclared and a JSON key whose value is JSON null. +This JSON library solves the problem by using Java null for the common case of an undeclared JSON +key, and a special "magic" instance of String ([`Data.NULL_STRING`][null-string]) to identify it as +a JSON null rather than a normal value. + +The following example shows how you might take advantage of this functionality: + +```java +private static void show(List items) { + for (Item item : items) { + System.out.println("ID: " + item.id); + if (item.value == null) { + System.out.println("No Value"); + } else if (Data.isNull(item.value)) { + System.out.print("Null Value"); + } else { + System.out.println("Value: '" + item.value + "'"); + } + } +} +``` + +[json-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/JsonFactory.html +[jackson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/jackson2/JacksonFactory.html +[jackson]: https://github.com/FasterXML/jackson +[gson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/gson/GsonFactory.html +[gson]: https://github.com/google/gson +[android-json-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/android/json/AndroidJsonFactory.html +[google-plus-sample]: https://github.com/googleapis/google-http-java-client/tree/master/samples/googleplus-simple-cmdline-sample +[json-parser]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/JsonParser.html +[key-annotation]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/Key.html +[generic-json]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/GenericJson.html +[map]: https://docs.oracle.com/javase/7/docs/api/java/util/Map.html +[null-string]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/Data.html#NULL_STRING diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 000000000..ec8b6b23f --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,80 @@ +--- +title: Setup Instructions +--- + +# Setup Instructions + +You can download the Google HTTP Client Library for Java and its dependencies in a zip file, or you +can use a dependency manager such as Maven or gradle to install the necessary jars from the Maven +Central repository. + +## Maven + +The Google HTTP Client Library for Java is in the central Maven repository. The Maven `groupId` for +all artifacts for this library is `com.google.http-client`. + +To ensure all dependency versions work together and to avoid having to manually choose and specify +versions for each dependency, we recommend first importing the `com.google.cloud:libraries-bom` in +the `dependencyManagement` section of your `pom.xml`: + +```xml + + + + com.google.cloud + libraries-bom + 2.2.1 + pom + import + + + +``` + +Then you add the individual dependencies you need without version numbers to the `dependencies` +section: + +```xml + + com.google.http-client + google-http-client + +``` + +On Android, you may need to explicitly exclude unused dependencies: +```xml + + com.google.http-client + google-http-client + + + xpp3 + xpp3 + + + httpclient + org.apache.httpcomponents + + + junit + junit + + + android + com.google.android + + + +``` + +## Download the library with dependencies + +Download the latest assembly zip file from Maven Central and extract it on your computer. This zip +contains the client library class jar files and the associated source jar files for each artifact +and their dependencies. You can find dependency graphs and licenses for the different libraries in +the dependencies folder. For more details about the contents of the download, see the contained +`readme.html` file. + + + + diff --git a/docs/unit-testing.md b/docs/unit-testing.md new file mode 100644 index 000000000..b5568a3ff --- /dev/null +++ b/docs/unit-testing.md @@ -0,0 +1,52 @@ +--- +title: HTTP Unit Testing +--- + +# HTTP Unit Testing + +When writing unit tests using this HTTP framework, don't make requests to a real server. Instead, +mock the HTTP transport and inject fake HTTP requests and responses. The +[pluggable HTTP transport layer][transport] of the Google HTTP Client Library for Java makes this +flexible and simple to do. + +Also, some useful testing utilities are included in the +[`com.google.api.client.testing.http`][testing-package] package (`@Beta`). + +The following simple example generates a basic `HttpResponse`: + +```java +HttpTransport transport = new MockHttpTransport(); +HttpRequest request = transport.createRequestFactory().buildGetRequest(HttpTesting.SIMPLE_GENERIC_URL); +HttpResponse response = request.execute(); +``` + +The following example shows how to override the implementation of the `MockHttpTransport` class: + +```java +HttpTransport transport = new MockHttpTransport() { + @Override + public LowLevelHttpRequest buildRequest(String method, String url) throws IOException { + return new MockLowLevelHttpRequest() { + @Override + public LowLevelHttpResponse execute() throws IOException { + MockLowLevelHttpResponse response = new MockLowLevelHttpResponse(); + response.addHeader("custom_header", "value"); + response.setStatusCode(404); + response.setContentType(Json.MEDIA_TYPE); + response.setContent("{\"error\":\"not found\"}"); + return response; + } + }; + } +}; +HttpRequest request = transport.createRequestFactory().buildGetRequest(HttpTesting.SIMPLE_GENERIC_URL); +HttpResponse response = request.execute(); +``` + +For more examples, see the [`HttpResponseTest.java`][http-response-test] and +[`HttpRequestTest.java`][http-request-test] files. + +[transport]: https://googleapis.github.io/google-http-java-client/http-transport.html +[testing-package]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/testing/http/package-summary.html +[http-response-test]: https://github.com/googleapis/google-http-java-client/blob/master/google-http-client/src/test/java/com/google/api/client/http/HttpResponseTest.java +[http-request-test]: https://github.com/googleapis/google-http-java-client/blob/master/google-http-client/src/test/java/com/google/api/client/http/HttpRequestTest.java \ No newline at end of file