【问题标题】:Google + Domains API Quick start for java is not workingJava的Google + Domains API快速入门不起作用
【发布时间】:2013-12-21 08:04:27
【问题描述】:

我正在尝试使用 Google + 中提供的域 API,我正在尝试使用域范围委派来快速启动 java 我已按照步骤操作,并且我已要求我的域管理员授予对我在控制台创建的项目,恢复我可以编译java文件,但是当我运行时,我得到一个404错误,这里是代码:

 /*
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.plus.samples.quickstart.domains;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.plusDomains.PlusDomains;
import com.google.api.services.plusDomains.model.Acl;
import com.google.api.services.plusDomains.model.Activity;
import com.google.api.services.plusDomains.model.PlusDomainsAclentryResource;
import com.google.api.services.plusDomains.model.Person;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * Simple program to demonstrate the Google+ Domains API.
 *
 * This program shows how to authenticate an app for domain-wide delegation and how
 * to complete an activities.insert API call. For details on how to authenticate on
 * a per-user basis using OAuth 2.0, or for examples of other API calls, please see
 * the documentation at https://developers.google.com/+/domains/.
 *
 * @author joannasmith@google.com (Joanna Smith)
 */
public class DomainDelegation {
  /**
   * Update SERVICE_ACCOUNT_EMAIL with the email address of the service account for the client ID
   *  created in the developer console.
   */
  private static final String SERVICE_ACCOUNT_EMAIL = "example@developer.gserviceaccount.com";

  /**
   * Update SERVICE_ACCOUNT_PKCS12_FILE_PATH with the file path to the private key file downloaded
   *  from the developer console.
   */
  private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH =
      "file-privatekey.p12";

  /**
   * Update USER_EMAIL with the email address of the user within your domain that you would like
   *  to act on behalf of.
   */
  private static final String USER_EMAIL = "example@email.com";


  /**
   * plus.me and plus.stream.write are the scopes required to perform the tasks in this quickstart.
   *  For a full list of available scopes and their uses, please see the documentation.
   */
  private static final List<String> SCOPE = Arrays.asList(
      "https://www.googleapis.com/auth/plus.me",
      "https://www.googleapis.com/auth/plus.stream.write",
      "https://www.googleapis.com/auth/plus.circles.read",
      "https://www.googleapis.com/auth/plus.profiles.read",
      "https://www.googleapis.com/auth/plus.stream.read",
      "https://www.googleapis.com/auth/userinfo.profile");


  /**
   * Builds and returns a Plus service object authorized with the service accounts
   * that act on behalf of the given user.
   *
   * @return Plus service object that is ready to make requests.
   * @throws GeneralSecurityException if authentication fails.
   * @throws IOException if authentication fails.
   */
  private static PlusDomains authenticate() throws GeneralSecurityException, IOException {

    System.out.println(String.format("Authenticate the domain for %s", USER_EMAIL));

    HttpTransport httpTransport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    // Setting the sub field with USER_EMAIL allows you to make API calls using the special keyword 
    // 'me' in place of a user id for that user.
    GoogleCredential credential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
        .setServiceAccountScopes(SCOPE)
        .setServiceAccountUser(USER_EMAIL)
        .setServiceAccountPrivateKeyFromP12File(
            new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
        .build();

    System.out.println("credential " + credential);
    // Create and return the Plus service object
    PlusDomains service = new PlusDomains.Builder(httpTransport, jsonFactory, credential).build();

    return service;
  }

  /**
   * Create a new post on behalf of the user associated with the credential object of the service,
   * restricted to the domain.
   *
   * @param service Plus service object that is ready to make requests.
   * @throws IOException if the insert operation fails or if authentication fails.
   * @throws GeneralSecurityException if authentication fails.
   */
  public static void main(String[] args) throws Exception {
    // Create an authorized API client
    PlusDomains service = authenticate();

    // Set the user's ID to 'me': requires the plus.me scope
    String userId = "me";
    String msg = "Happy Monday! #caseofthemondays";

    System.out.println("Inserting activity " + service);

    // Create the audience of the post
    PlusDomainsAclentryResource res = new PlusDomainsAclentryResource();

    // Share to the domain
    res.setType("domain");


    List<PlusDomainsAclentryResource> aclEntries = new ArrayList<PlusDomainsAclentryResource>();
    aclEntries.add(res);

    Acl acl = new Acl();
    acl.setItems(aclEntries);

    // Required, this does the domain restriction
    acl.setDomainRestricted(true);

    Activity activity = new Activity()
        .setObject(new Activity.PlusDomainsObject().setOriginalContent(msg))
        .setAccess(acl);
    //System.out.println("ativity " + activity);

    activity = service.activities().insert(userId, activity).execute();

    System.out.println(activity);
  }
}

显然,我的代码中的电子邮件和密钥文件等数据是正确的,这是我得到的错误:

Authenticate the domain for example@email.com
credential com.google.api.client.googleapis.auth.oauth2.GoogleCredential@2b275d39
04-dic-2013 8:59:50 com.google.api.client.googleapis.services.AbstractGoogleClient <init>
ADVERTENCIA: Application name is not set. Call Builder#setApplicationName.
Inserting activity com.google.api.services.plusDomains.PlusDomains@46b8c8e6
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
Not Found
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1045)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at com.google.plus.samples.quickstart.domains.DomainDelegation.main(DomainDelegation.java:154)

我迷路了,如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 您是在 Google Cloud Console 还是在旧版 Google APIs Console 中创建了您的客户端 ID?
  • Java 快速入门中的链接似乎是较旧的 Google API 控制台,当我将鼠标悬停在链接中时,这是地址:developer.google.com/console,但我没有点击该链接,我转到较旧的控制台,在您发表评论后,我单击链接并被带到我未使用的其他控制台,有区别吗?
  • 我最近听说新控制台中的服务帐户凭据无法正常工作的问题。但不确定是否仍然如此。
  • 好吧,我将尝试其他选项,您是否在第一次回复中看到我对我用来创建客户端 ID 的服务的评论?你认为这可能是个问题吗?
  • 对我来说更奇怪的是响应是404错误未找到,不是授予访问的问题,看起来有些东西坏了,但我必须使用所有的建议和选项.

标签: java google-api google-plus google-api-java-client google-authentication


【解决方案1】:

现在看来,包含 PlusDomains.builder 的行需要调用 setApplicationName:

PlusDomains service = new PlusDomains.Builder(httpTransport, jsonFactory, credential)
  .setApplicationName('MyDomainsDemo')
  .build();

【讨论】:

  • 我提出了你的建议,但我仍然有同样的问题,我必须添加一些东西,我用于生成客户端 ID、电子邮件和私钥文件的服务帐户正是服务帐户我公司的,所以这个帐户没有关联 G+ 帐户,那么我不知道这个功能是否会影响,我还阅读了文档中的常见问题解答部分,并提到了我的 java 文件和我的管理员授予的权限,它说它必须按照相同的顺序,我认为这不是原因,但是您对提到的内容有何看法?
  • 帐户无需是 Google+ 帐户即可创建凭据。我们将看看是否可以重现问题。
  • 谢谢你,如果你能帮助我,我将不胜感激。
  • @JohnB 尝试此解决方案后您的日志显示了什么?因为应该通过这个来解决。
  • @Jhanvi 在结果中我得到同样的错误,使用 setApplicationName 时唯一改变的部分是这两行消失了:13-dic-2013 9:25:29 com.google.api。 client.googleapis.services.AbstractGoogleClient 广告:未设置应用程序名称。调用 Builder#setApplicationName。但是出现了同样的错误,有什么想法吗??
【解决方案2】:

我今天测试了 Java 示例,它工作正常。说明需要在 API 控制台中与标签更改相关的一些小更新,但如果您正确配置应用程序,您将能够开始。

404 错误很可能是由错误配置的客户端引起的,而不是示例中的问题。以下屏幕截图应该有助于获取正确的凭据。创建服务帐户后,您将在下面突出显示一个新区域:

确保 服务帐号 下的客户端 ID 与您在管理控制台执行域范围委派时添加的客户端 ID 相同。以下屏幕截图显示了客户端 ID(上一个屏幕截图中的第一个字段)的去向:

最后,确保src/com/google/plus/samples/quickstart/domains/DomainDelegation.java 中配置的电子邮件地址与您的服务帐户中的电子邮件匹配。

如果您使用的是经典 API 控制台,则需要将服务帐户添加到您的项目,通过 API 访问执行此操作 -> 创建另一个客户端 ID... -> 服务帐户。然后这些值将来自添加的部分:

【讨论】:

  • 好的,我会尝试检查一切是否到位,为什么在您的第一个屏幕截图中出现 Web 应用程序的客户端 ID?与服务帐户无关?我还有其他问题,我用来创建服务帐户的帐户不是管理员帐户也没关系,对吧?或者我必须使用管理员帐户来创建服务帐户
  • 我测试的帐户是管理员帐户,我不确定是否需要,但这可能是您的问题。让我知道将您的帐户更改为管理员是否有帮助,以便我可以适当地修改我的答案。
  • 在您附加的屏幕截图中,我看到您正在使用 Google 的新控制台进行项目,在我的情况下,我从旧控制台获得了凭证,您认为它可能会产生某种麻烦这个功能?
  • 经典的 API 控制台仍然可以工作,您只需要创建服务帐户凭据并使用它们。
  • 好的,那么我假设在您的屏幕截图中,Web 应用程序的客户端 ID 部分不相关?还是我遗漏了什么?
【解决方案3】:

这行得通!

用那些罐子

antlr-2.7.7.jar jackson-core-asl-1.9.11.jar aopalliance-1.0.jar javassist-3.15.0-GA.jar commons-email-1.3.2.jar jboss-logging-3.1.0.GA.jar commons-logging-1.1.1.jar jboss-transaction-api_1.1_spec-1.0.0.Final.jar dom4j-1.6.1.jar jsr305-1.3.9.jar google-api-client-1.17.0-rc.jar jstl-1.2.jar google-api-client-jackson2-1.17.0-rc-sources.jar mail-1.4.1.jar google-api-services-calendar-v3-rev87-1.19.0.jar mysql-connector-java-5.1.22.jar google-collections-1.0-rc2.jar spring-aop-3.2.2.RELEASE.jar google-http-client-1.17.0-rc.jar spring-beans-3.2.2.RELEASE.jar google-http-client-jackson-1.17.0-rc.jar spring-context-3.2.2.RELEASE.jar google-oauth-client-1.17.0-rc.jar spring-core-3.2.2.RELEASE.jar google-oauth-client-servlet-1.17.0-rc.jar spring-expression-3.2.2.RELEASE.jar hibernate-commons-annotations-4.0.1.Final.jar spring-jdbc-3.2.2.RELEASE.jar hibernate-core-4.1.10.Final.jar spring-orm-3.2.2.RELEASE.jar hibernate-jpa-2.0-api-1.0.1.Final.jar spring-tx-3.2.2.RELEASE.jar hsqldb-2.2.9.jar spring-web-3.2.2.RELEASE.jar httpclient-4.0.1.jar spring-webmvc-3.2.2.RELEASE.jar httpcore-4.0.1.jar transaction-api-1.1.jar jackson-core-2.1.3.jar

...

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.TimeZone;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
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.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventAttendee;
import com.google.api.services.calendar.model.EventDateTime;

..

public class GoogleCalNotificator {
public static void addEvent(TurnosRepository repo, String fecha,
            String inicio, String fin, String paciente, String cliente) {

    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();
    String scope = "https://www.googleapis.com/auth/calendar";

    GoogleCredential credential = null;
    try {
        credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                .setServiceAccountId(
                        "xxxxxxxxxxx@developer.gserviceaccount.com")
                .setServiceAccountUser("xxxxxxxxx@gmail.com")
                .setServiceAccountScopes(Arrays.asList(scope))
                .setServiceAccountPrivateKeyFromP12File(
                        new File(repo.getParameter("P12_FILE"))) //p12 from gooleapiuser

                .build();
    } catch (GeneralSecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Calendar service = new Calendar.Builder(httpTransport, jsonFactory,
            credential).setApplicationName("appname").build();

    // -----------------
    Event event = new Event();

    event.setSummary("text " );
    event.setLocation("loc ");

    ArrayList<EventAttendee> attendees = new ArrayList<EventAttendee>();
    attendees.add(new EventAttendee().setEmail("xxxxxx@gmail.com"));
    // ...
    event.setAttendees(attendees);

    Date startDate = null;
    Date endDate = null;
    try {
        startDate = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(fecha
                + " " + inicio);
        endDate = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(fecha
                + " " + fin);

    } catch (ParseException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    DateTime start = new DateTime(startDate, TimeZone.getTimeZone("America/Argentina/Buenos_Aires"));
    event.setStart(new EventDateTime().setDateTime(start));
    DateTime end = new DateTime(endDate, TimeZone.getTimeZone("America/Argentina/Buenos_Aires"));
    event.setEnd(new EventDateTime().setDateTime(end));

    // lo pongo en el calendario de julia
    try {
        Event createdEvent = service
                .events()
                .insert("xxxxxxxxidfromcalendar@group.calendar.google.com",
                        event).execute();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}

【讨论】:

  • 我尝试使用我的凭据运行您的代码并得到:“com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized”。你知道为什么吗?
【解决方案4】:

我最近遇到了这个问题。对我来说,解决方案是更新库(示例在 lib/ 文件夹中带有一堆过时的 JAR)。

我的 Maven 依赖项:

<dependencies>
    <dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client</artifactId>
        <version>1.23.0</version>
    </dependency>

    <dependency>
        <groupId>com.google.apis</groupId>
        <artifactId>google-api-services-plusDomains</artifactId>
        <version>v1-rev449-1.23.0</version>
    </dependency>

    <dependency>
        <groupId>com.google.http-client</groupId>
        <artifactId>google-http-client-jackson</artifactId>
        <version>1.23.0</version>
    </dependency>
</dependencies>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-06
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    相关资源
    最近更新 更多