What is an example of using OAuth 2.0 and Google Spreadsheet API with Java?

13,270

Solution 1

Answer moved from original question to match site "Q and A" format.

The Google Data Java Client Library supports OAuth 2.0. Unfortunately, there are no complete samples in the library showing how to use it with the Google Spreadsheet API.

Here is an example that has worked for me. I hope someone find it helpful.

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.gdata.util.ServiceException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class NewClass {

  // Retrieve the CLIENT_ID and CLIENT_SECRET from an APIs Console project:
  //     https://code.google.com/apis/console
  static String CLIENT_ID = "your-client-id";
  static String CLIENT_SECRET = "your-client-secret";
  // Change the REDIRECT_URI value to your registered redirect URI for web
  // applications.
  static String REDIRECT_URI = "the-redirect-uri";
  // Add other requested scopes.
  static List<String> SCOPES = Arrays.asList("https://spreadsheets.google.com/feeds");


public static void main (String args[]) throws IOException, ServiceException, com.google.protobuf.ServiceException{
    Credential credencial = getCredentials();
    JavaApplication20.printDocuments(credencial);
}


  /**
   * Retrieve OAuth 2.0 credentials.
   * 
   * @return OAuth 2.0 Credential instance.
   */
  static Credential getCredentials() throws IOException {
    HttpTransport transport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();

    // Step 1: Authorize -->
    String authorizationUrl =
        new GoogleAuthorizationCodeRequestUrl(CLIENT_ID, REDIRECT_URI, SCOPES).build();

    // Point or redirect your user to the authorizationUrl.
    System.out.println("Go to the following link in your browser:");
    System.out.println(authorizationUrl);

    // Read the authorization code from the standard input stream.
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("What is the authorization code?");
    String code = in.readLine();
    // End of Step 1 <--

    // Step 2: Exchange -->
    GoogleTokenResponse response =
        new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, CLIENT_ID, CLIENT_SECRET,
            code, REDIRECT_URI).execute();
    // End of Step 2 <--

    // Build a new GoogleCredential instance and return it.
    return new GoogleCredential.Builder().setClientSecrets(CLIENT_ID, CLIENT_SECRET)
        .setJsonFactory(jsonFactory).setTransport(transport).build()
     .setAccessToken(response.getAccessToken()).setRefreshToken(response.getRefreshToken());
  }

  // …
}

Here the other Class:

import com.google.api.client.auth.oauth2.Credential;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListFeed;
import com.google.gdata.data.docs.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.CellEntry;
import com.google.gdata.data.spreadsheet.CellFeed;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.data.spreadsheet.WorksheetEntry;
import com.google.gdata.data.spreadsheet.WorksheetFeed;
import com.google.gdata.util.ServiceException;
// ...
import java.io.IOException;
import java.net.URL;
import java.util.List;
// ...

public class JavaApplication20 {
  // …

  static void printDocuments(Credential credential) throws IOException, ServiceException {
    // Instantiate and authorize a new SpreadsheetService object.

     SpreadsheetService service =
            new SpreadsheetService("Aplication-name");
     service.setOAuth2Credentials(credential);
    // Send a request to the Documents List API to retrieve document entries.
    URL SPREADSHEET_FEED_URL = new URL(
        "https://spreadsheets.google.com/feeds/spreadsheets/private/full");
    // Make a request to the API and get all spreadsheets.
    SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL,
        SpreadsheetFeed.class);
    List<com.google.gdata.data.spreadsheet.SpreadsheetEntry> spreadsheets = feed.getEntries();
     if (spreadsheets.isEmpty()) {
      // TODO: There were no spreadsheets, act accordingly.
    }
com.google.gdata.data.spreadsheet.SpreadsheetEntry spreadsheet = spreadsheets.get(0);
    System.out.println(spreadsheet.getTitle().getPlainText());
// Get the first worksheet of the first spreadsheet.
    // TODO: Choose a worksheet more intelligently based on your
    // app's needs.
    WorksheetFeed worksheetFeed = service.getFeed(
        spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
    List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
    WorksheetEntry worksheet = worksheets.get(0);

    // Fetch the cell feed of the worksheet.
    URL cellFeedUrl = worksheet.getCellFeedUrl();
    CellFeed cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);

    // Iterate through each cell, printing its value.
    for (CellEntry cell : cellFeed.getEntries()) {
      // Print the cell's address in A1 notation
      System.out.print(cell.getTitle().getPlainText() + "\t");
      // Print the cell's address in R1C1 notation
      System.out.print(cell.getId().substring(cell.getId().lastIndexOf('/') + 1) + "\t");
      // Print the cell's formula or text value
      System.out.print(cell.getCell().getInputValue() + "\t");
      // Print the cell's calculated value if the cell's value is numeric
      // Prints empty string if cell's value is not numeric
      System.out.print(cell.getCell().getNumericValue() + "\t");
      // Print the cell's displayed value (useful if the cell has a formula)
      System.out.println(cell.getCell().getValue() + "\t");
    }

  }

  // ...
}

Solution 2

You can find a step by step explanation with examples here. As a result, your code might look like this:

SpreadsheetService service = new SpreadsheetService("MySpreadsheetIntegration-v1");
service.setProtocolVersion(SpreadsheetService.Versions.V1); // It's important to specify the version

service.setRequestFactory(makeAuthorization());

SpreadsheetQuery q = new SpreadsheetQuery(new URL(DEFAULT_SPREADSHEET_QUERY));

SpreadsheetFeed feed;
try {
  feed = service.query(q, SpreadsheetFeed.class);
}
catch (AuthenticationException e) {
  refreshAccessToken(service);

  feed = service.query(q, SpreadsheetFeed.class);
}

SpreadsheetEntry spreadsheet = findSpreadSheet(feed);

...

// do your stuff

...

// a couple of utility methods are used above:

private void refreshAccessToken(SpreadsheetService service) throws Exception {
  String accessToken = callGetAccessTokenApi();

  // save access token

  service.getRequestFactory().setAuthToken(new GoogleAuthTokenFactory.OAuth2Token(new GoogleCredential().setAccessToken(accessToken)));
}

//private static final String GOOGLE_API_HOST = "https://www.googleapis.com/";

private String callGetAccessTokenApi() throws Exception {
  HttpClient client = HttpClients.createDefault();

  String url = String.format(
    "%soauth2/v3/token?client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token",
    GOOGLE_API_HOST,
    googleAuthorization.getClientId(),
    googleAuthorization.getClientSecret(),
    googleAuthorization.getRefreshToken()
  );
  HttpPost post = new HttpPost(url);
  post.addHeader(ACCEPT_HEADER_NAME, "application/x-www-form-urlencoded");

  try {
    HttpResponse response = client.execute(post);

    JSONObject object = readJson(response);

    return object.getString("access_token");
  }
  finally {
    post.releaseConnection();
  }
}

private Service.GDataRequestFactory makeAuthorization() {
  Service.GDataRequestFactory requestFactory = new HttpGDataRequest.Factory();

  // load access token

  requestFactory.setAuthToken(new GoogleAuthTokenFactory.OAuth2Token(new GoogleCredential().setAccessToken(accessToken)));

  return requestFactory;
}
Share:
13,270

Related videos on Youtube

user2952212
Author by

user2952212

Updated on January 29, 2020

Comments

  • user2952212
    user2952212 over 4 years

    Where is example code showing how to use the Google Data Java Client Library and its support for OAuth 2.0 with the Google Spreadsheet API (now called the Google Sheets API)?

    • eddyparkinson
      eddyparkinson over 10 years
      Looks good. Maybe add code to get the access token from the refresh token. ... Also would be fitting to convert this into question and answer format.
    • ErstwhileIII
      ErstwhileIII almost 10 years
      Hmm this is an answer masquerading as a question?! ... I think I will restructure this as a Q and A.
  • Moshe Shaham
    Moshe Shaham over 9 years
    this helped me a lot, thanks you. It should be noted that in most cases you actually want to access the spreadsheet with refresh token rather than access token
  • eddyparkinson
    eddyparkinson over 9 years
    @MosheShaham I think you mean: the access token expires after about 1 hour and you need to get a new access token using the refresh token.
  • Ofek Agmon
    Ofek Agmon over 9 years
    in android application (installed application) google provides only client ID (don't have client secret). I want to edit a google spreadsheet from my android app, how should I use this example with no Client secret?
  • Dimitris Sfounis
    Dimitris Sfounis about 9 years
    How do you set up the redirect URI, for a desktop application? Your answer is hardly of any use.
  • Ker p pag
    Ker p pag about 9 years
    where did you get the application name? I get an exception says "com.google.gdata.util.AuthenticationException: Error authenticating (check service name)"
  • Sumeet Vishwas
    Sumeet Vishwas about 7 years
    SpreadsheetService do not have setOAuth2Credentials function. I am using gdata-spreadsheet-3.0.jar. I am stuck at time point. Please help me with finding solution