My favorites | English | Sign in

Google Health Data API

Developer's Guide: Java 1.5

Important: This is an old version of this page. For the latest version, use the links in the left-side navbar.

The Google Health Data API allows client applications to view and update Health content in the form of Google Data API feeds. Your client application can request a user's profile as a CCR document, retrieve a list of notices sent to their account, or send a notice to a user.

In addition to providing some background on the capabilities of the Health Data API, this document provides examples for interacting with the API using the Java client library. This document provides Java 1.5 specifics for performing the general actions described in the developer's guide overview page.

Contents

Audience

This document is intended for programmers who want to write client applications using the Google Data API Java client library that can interact with Google Health. The following instructions assume some knowledge of building, deploying, and running Java web applications.

Getting started

For help getting started with Google Data API Java client library, see Getting Started with the Java Client Library.

To use the Java client library, you must be running Java 1.5 or higher. You must also be running Apache Ant, and either a servlet container such as Apache Tomcat or full app server such as JBoss.

In addition, you should download the following libraries and update the relevant build.properties files to point to the correct location of the dependencies.

Download the full source code of a working sample application that works with the H9 Sandbox.

To build the application, use the included build.xml file with Apache Ant to compile a WAR file in the deploy directory. Deploy this file to your servlet container. Tomcat's default configuration, for example, will auto-deploy the war file if it is copied to root/webapps.

You should then be able to access this application at http://hostname:port/Health

Note: The sample application currently doesn't have much error feedback to the end-user visiting the application. Most exceptions are caught and logged to stderr, so please look at the server error logs if you are experiencing any problems with this application. In Tomcat, for instance, these errors would be logged to catalina_root/logs/catalina.out.

Error handling has been removed from this document. To see a complete implementation, including error handling, download the full source sample.

Back to top

Authenticating to the Health service

AuthSub Authentication

The AuthSub login protocol allows your web-based application to have a user authenticate through Google's servers.

Generating an AuthSub URL

You must specifically modify the AuthSub URL for both Google Health and the H9 Developer's Sandbox. Each use a special AuthSub handler and the Java client library doesn't allow you to modify the location of Google's AuthSub server at this time.

The following code sets a service object for H9 and generates an AuthSub URL:

H9Service h9Service = new H9Service("exampleCo-H9Sample-1.0");

String nextUrl = "http://localhost:port/Health";
String scope = "https://www.google.com/h9/feeds/";
boolean secure = false;
boolean session = true;
String authSubLink = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

// This will default the security settings to be the most permissive.
authSubLink += "&permission=1";

// We have a custom AuthSub handler for Health.
authSubLink = authSubLink.replaceFirst("/accounts/AuthSubRequest", "/h9/authsub");

String link = "<a href=\"" + authSubLink + "\">Link your H9 Profile</a>";
...

The single parameter is the name of your application in the form companyName-applicationName-versionID.

If you're ready to move to production, here's how to set a service object for Health and generate the AuthSub URL:

HealthService HealthService = new healthService("exampleCo-HealthSample-1.0");

String nextUrl = "http://www.example.com/health.jsp";
String scope = "https://www.google.com/health/feeds/";
boolean secure = true;
boolean session = true;
String authSubLink = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

// This will default the security settings to be the most permissive.
authSubLink += "&permission=1";

// We have a custom AuthSub handler for Health.
authSubLink = authSubLink.replaceFirst("/accounts/AuthSubRequest", "/health/authsub");

String link = "<a href=\"" + authSubLink + "\">Link your Google Health Profile</a>";
...

Note: Before you can interact with Google Health, you must register your application with Google and Google Health. Please see Domain Registration & Signing Requests in the Getting Started Guide.

Upgrading to a session token

After a successfully authorization from AuthSub, the user returns to your next URL with a single-use token appended to the end. For example, http://www.example.com/health.jsp?token=singleUseToken.

To extract the single-use token and exchange it for a session token, use the following on H9:

String singleUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());
String sessionToken = AuthSubUtil.exchangeForSessionToken(URLDecoder.decode(singleUseToken, "UTF-8"), null);

h9Service.setAuthSubToken(sessionToken);

// query an H9 feed

This procedure is slightly for sophisticated for Google Health. The token upgrade and call to setAuthSubToken must include your Java keystore:

String singleUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());

PrivateKey privateKey = AuthSubUtil.getPrivateKeyFromKeystore("keystore.jks", "keystorePass", "keyAlias", "keyPass");
String sessionToken = AuthSubUtil.exchangeForSessionToken(URLDecoder.decode(singleUseToken, "UTF-8"), privateKey);

healthService.setAuthSubToken(sessionToken, privateKey);

// query a health feed

The call to setAuthSubToken sets the healthService object with the session token and your privateKey. You don't need to worry about setting these values on subsequent requests.

For help creating a the keystore file, see Creating a self-signing X.509 public certificate in the Getting Started Guide.

ClientLogin username/password authentication

Use ClientLogin authentication if your client is a standalone, single-user "installed" client (such as a desktop application). Just call the setUserCredentials method on your H9Service or HealthService object and all subsequent interactions will be authenticated:

For H9:

H9Service h9Service = new H9Service("exampleCo-HealthSample-1.0");
h9Service.setUserCredentials("user@domain.com", "secretPassword");

For Google Health:

HealthService healthService = new HealthService("exampleCo-HealthSample-1.0");
healthService.setUserCredentials("user@domain.com", "secretPassword");

In the snippets above, we pass a single parameter to the service constructor, the name of our application in the form companyName-applicationName-versionID.

For more information about ClientLogin authentication, including sample requests and responses, see the Authentication for Installed Applications documentation.

Note: Use the same token for all requests in a given session; don't acquire a new token for each Health request.

Note: As described in the ClientLogin documentation, the authentication request may fail and request a CAPTCHA challenge. If you want Google to issue and handle the CAPTCHA challenge, then send the user to https://www.google.com/accounts/DisplayUnlockCaptcha?service=health (rather than to the CAPTCHA-handling URL given in the ClientLogin documentation).

Back to top

Get a user's profile

The profile feed allows you to retrieve a CCR document describing a user's health information stored with Google. Each profile is encapsulated inside of an Atom entry. The Java client library can be used to extract the CCR information and print it to the page.

The following example shows how to query the profile feed. It assumes that the HealthService constructor has already been called and set to healthService.

Query query = new Query(new URL("https://www.google.com/health/feeds/profile/default"));
query.addCustomParameter(new Query.CustomParameter("digest", "true"));

try {
  Feed result = healthService.getFeed(query, Feed.class);

  // We used the digest=true parameter, so there should only
  // be a single Atom entry that contains all of the CCR data in profile.
  for (Entry entry : result.getEntries()) {
    System.out.println(entry.getXmlBlob().getBlob());
  }
}
...

Back to top

Interacting with the register feed

Notices are the primary means by which your application can communicate and interact with the user. They allow you to send informational messages and CCR profile data to a user. Currently, the only thing you can do using AuthSub is post new notices; you can't update or delete notices using AuthSub. ClientLogin allows for reading existing notices, posting new notices, and updating or deleting notices.

Get a list of notices

Note: This feature is available only with ClientLogin.

You can retrieve notices that your application has access to view using the register feed in conjunction with a profile ID: register/ui/profileID. Note that you can use query parameters to narrow down the results of this query.

The following code retrieves all of the notices associated with the given profile. It also prints out any attached CCR data appended to a notice.

Query query = new Query(new
  URL("https://www.google.com/health/feeds/register/ui/profileID"));

try {
  Feed result = healthService.query(query, Feed.class);

  for (Entry entry : result.getEntries()) {
    // Display author
    System.out.println(entry.getAuthors().get(0).getName());

    // Display date sent
    System.out.println(entry.getPublished().toString());

    // Get subject of notice
    System.out.println(entry.getTitle().getPlainText());

    // Get notice message body
    TextContent content = (TextContent) entry.getContent();
    System.out.println(content.getContent().getPlainText());

    // Print out CCR information attached to the notice
    if (entry.getXmlBlob().getBlob().length() > 0) {
      System.out.println(entry.getXmlBlob().getBlob());
    }
  }
}

...

Send a notice

Creating a new notice is accomplished by constructing an Atom entry and sending an HTTP POST to the register feed.

CCR data can be included with your notice. The below code shows adding a CCR fragment from a string variable called ccr.

Entry newNotice = new Entry();

newNotice.setTitle(new PlainTextConstruct(yourSubject));
newNotice.setContent(new PlainTextConstruct(yourMessage));

if (ccr != null) {
  XmlBlob ccrElement = new XmlBlob();
  ccrElement.setBlob(ccr);
  newNotice.setXmlBlob(ccrElement);
}

try {
  Entry createdNotice = service.insert(new URL("https://www.google.com/health/feeds/register/default"), newNotice);
}
...

Back to top