如何从外部目录java调用client_secrets.json?

时间:2017-11-21 08:23:52

标签: java json youtube-api youtube-data-api

我基本上有一个动态的WEB-APP,通过servlet我试图检索youtube视频评论。

虽然网上有很多关于它的文章,但我不知道为什么没有一个对我有用。

第一次尝试:

private static int counter = 0;
private static YouTube youtube;

public static void getYoutubeOauth() throws Exception {
    List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");

    Credential credential = Auth.authorize(scopes, "commentthreads");
    youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();

    String videoId = "KIgxmV9xXBQ";

    // Get video comments threads
    CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();

    while (true) {
        handleCommentsThreads(commentsPage.getItems());

        String nextPageToken = commentsPage.getNextPageToken();
        if (nextPageToken == null)
            break;

        // Get next page of video comments threads
        commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
    }

    System.out.println("Total: " + counter);
}

有了这个,我在第Credential credential = Auth.authorize(scopes, "commentthreads");

行获得了nullpointerexception

如果你能解释什么是scope,你从哪里得到它。

第二次尝试我尝试创建一个不同的函数来获取凭据。

第二次尝试:

   public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";

public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {

    // Load client secrets.
    Reader clientSecretReader = new InputStreamReader(
            Auth.class.getResourceAsStream("/home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json"));
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);

    // Checks that the defaults have been replaced (Default = "Enter X here").
    if (clientSecrets.getDetails().getClientId().startsWith("Enter")
            || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
        System.out.println(
                "Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
                        + "into src/main/resources/client_secrets.json");
        return null;
    }

    // This creates the credentials datastore at ~/.oauth-credentials/${credentialDatastore}
    FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
    DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
            .build();

    // Build the local server and bind it to port 8080
    LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();

    // Authorize.
    return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}

这里我也在第Reader clientSecretReader = new InputStreamReader(...行获得了nullpointerexception,虽然如果我在终端尝试nano /home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json,我可以访问该文件。

问题:如何授权我的网络应用并从外部目录中读取client_secrets.json。

1 个答案:

答案 0 :(得分:0)

有点痛苦,但让第二个解决方案有效。

所以我错误的是我正在调用Auth.class.getResourceAsStream,它要求数据可供classLoader使用,但我的classLoader则不是。

所以我要做的就是从外部目录请求我的client_secrets.json,然后你必须使用FileInputStream以外的getResourceAsStream

FileInputStreamgetResourceAsStream都可以正常运行,但它们的情况和代码不同。

public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";

public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
    Reader clientSecretReader = new InputStreamReader(
            new FileInputStream("/client_secrets.json"));
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
    System.out.println(clientSecretReader.toString());
    if (clientSecrets.getDetails().getClientId().startsWith("Enter")
            || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
        System.out.println(
                "Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
                        + "into src/main/resources/client_secrets.json");
        return null;
    }
    FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
    DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
            .build();
    LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8081).build();

    return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}

private static int counter = 0;
private static YouTube youtube;

public static void getYoutubeOauth() throws Exception {
    List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
    Credential credential = authorize(scopes, "commentthreads");
    youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();

    String videoId = "KIgxmV9xXBQ";

    // Get video comments threads
    CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();

    while (true) {
        handleCommentsThreads(commentsPage.getItems());

        String nextPageToken = commentsPage.getNextPageToken();
        if (nextPageToken == null)
            break;

        commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
    }

    System.out.println("Total: " + counter);
}

private static YouTube.CommentThreads.List prepareListRequest(String videoId) throws Exception {

    return youtube.commentThreads()
                  .list("snippet,replies")
                  .setVideoId(videoId)
                  .setMaxResults(100L)
                  .setModerationStatus("published")
                  .setTextFormat("plainText");
}

private static void handleCommentsThreads(List<CommentThread> commentThreads) {

    for (CommentThread commentThread : commentThreads) {
        List<Comment> comments = Lists.newArrayList();
        comments.add(commentThread.getSnippet().getTopLevelComment());

        CommentThreadReplies replies = commentThread.getReplies();
        if (replies != null)
            comments.addAll(replies.getComments());

        System.out.println("Found " + comments.size() + " comments.");

        // Do your comments logic here
        counter += comments.size();
    }
}

注意:FileInputStream位置更改为您自己的位置。

然后你可以致电getYoutubeOauth并希望得到一份有效的回复:)