将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是啥?

Posted

技术标签:

【中文标题】将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是啥?【英文标题】:What is an example of using OAuth 2.0 and Google Spreadsheet API with Java?将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是什么? 【发布时间】:2014-02-21 18:55:23 【问题描述】:

显示如何使用Google Data Java Client Library 及其对OAuth 2.0Google Spreadsheet API(现在称为Google Sheets API)的支持的示例代码在哪里?

【问题讨论】:

看起来不错。也许添加代码以从刷新令牌中获取访问令牌。 ...也适合将其转换为问答格式。 嗯,这是一个伪装成问题的答案?! ...我想我会将其重组为 Q 和 A。 【参考方案1】:

答案从原始问题转移到与网站“Q and A”格式相匹配。

Google Data Java Client Library 支持OAuth 2.0。 不幸的是,库中没有完整的示例来展示如何将它与Google Spreadsheet API 一起使用。

这是一个对我有用的例子。我希望有人觉得它有帮助。

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());
  

  // …

这里是另一个类:

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");
    

  

  // ...

【讨论】:

这对我帮助很大,谢谢。应该注意的是,在大多数情况下,您实际上希望使用刷新令牌而不是访问令牌来访问电子表格 @MosheShaham 我认为您的意思是:访问令牌在大约 1 小时后过期,您需要使用刷新令牌获取新的访问令牌。 android 应用程序(已安装的应用程序)中,谷歌仅提供客户端 ID(没有客户端密码)。我想从我的 Android 应用程序中编辑一个谷歌电子表格,我应该如何使用这个没有客户端密码的示例? 如何为桌面应用程序设置重定向 URI?你的回答几乎没有任何用处。 您从哪里获得应用程序名称的?我收到一个异常提示“com.google.gdata.util.AuthenticationException:身份验证错误(检查服务名称)”【参考方案2】:

您可以通过示例here 找到逐步说明。因此,您的代码可能如下所示:

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;

【讨论】:

【参考方案3】:

(2016 年 12 月) 此问题的大部分内容和此处的大多数答案现已过时,因为:1) GData APIs 是上一代 Google API。虽然并非所有 GData API 都已被弃用,但all modern Google APIs使用the Google Data protocol; 2) 2016 年的 Google released a new Google Sheets API v4(不是 GData)。要使用新的 API,您需要获取 the Google APIs Client Library for Java 并使用最新的 Sheets API,它比以前的任何 API 都更强大和灵活。

这里是 our Java Quickstart code sample,可帮助您继续使用 API——其中也包含 OAuth2 代码。此外,这里是the JavaDocs reference for the Sheets API,它概述了您可以使用的所有课程。如果您对 Python 没有“过敏”,我还制作了一段视频,了解 OAuth 授权代码和另一对视频,其中包含更多使用 Sheets API 的“真实世界”示例:

Accessing Google APIs: Common code walkthrough(代码深潜post) Migrating SQL data to a Sheet(代码深潜post) Formatting text using the Sheets API(代码深潜post)

最新的 API 提供了旧版本中没有的功能,即让开发人员可以像使用用户界面一样以编程方式访问工作表(创建冻结行、执行单元格格式设置、调整行/列大小、添加数据透视表、创建图表等)另请注意,此 API 主要用于上述的编程电子表格操作和功能。

要执行文件级访问,例如上传和下载、导入和导出(与上传和下载相同,但转换为/从各种格式),您可以改用 Google Drive API,下面是一对示例'已经创建(也是 Python):

(简单)将 Google 表格导出为 CSV (blogpost) (中级)“穷人的纯文本到 PDF”转换器 (blogpost) (*)

(*) - TL;DR:将纯文本文件上传到云端硬盘,导入/转换为 Google 文档格式,然后将该文档导出为 PDF。上面的帖子使用 Drive API v2; this follow-up post 描述了将其迁移到 Drive API v3,这是一个 developer video 结合了这两个帖子。

要详细了解如何使用 Google API(主要是 Python 或 javascript),请查看我制作的各种 Google 开发者视频(series 1 和 series 2)。

【讨论】:

以上是关于将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是啥?的主要内容,如果未能解决你的问题,请参考以下文章

无需 Oauth 令牌即可访问 Google 电子表格 API

需要Google OAuth 2.0架构建议通过Java邮件Api发送Smtp邮件

将使用 Google OAuth2.0 的登录电子邮件限制为特定域名

Google OAuth 2.0 服务帐户 - 日历 API(PHP 客户端)

使用Javascript中的Oauth授权将Google表格API v3迁移到v4之后如何实现makeApiCall()方法

Google API 和 OAuth 2.0 的正确重定向 URI