0

我用 Java 编写了一个 http post 请求来访问 Bigquery 数据。以下是我的代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
public class Post {

    static String url =
        "https://www.googleapis.com/bigquery/v2/projects/<project-ID>/queries?key=<API Broweser key>";

   public static void main(String[] args) throws Exception {

       //Instantiate an HttpClient
       HttpClient client = new HttpClient();

       //Instantiate a GET HTTP method
       PostMethod method = new PostMethod(url);
       method.setRequestHeader("Content-type",
               "application/json");
       method.setRequestHeader("Authorization",
               URLEncoder.encode("Bearer <authorization-token>","UTF-8"));

       //Define name-value pairs to set into the QueryString
       NameValuePair nvp1= new NameValuePair("query","select * from <TableName> limit 10");

       method.setQueryString(new NameValuePair[]{nvp1});

       try{
           int statusCode = client.executeMethod(method);

           System.out.println("Status Code = "+statusCode);
           System.out.println("QueryString>>> "+method.getQueryString());
           System.out.println("Status Text>>>"
                 +HttpStatus.getStatusText(statusCode));

           //Get data as a String
           System.out.println(method.getResponseBodyAsString());

           //OR as a byte array
           byte [] res  = method.getResponseBody();

           //write to file
           FileOutputStream fos= new FileOutputStream("donepage.html");
           fos.write(res);

           //release connection
           method.releaseConnection();
       }
       catch(IOException e) {
           e.printStackTrace();
       }
   }
}

我收到以下错误:

Unauthorized
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

请注意,我可以使用相同的授权令牌通过 BigQuery 命令行工具访问数据。我使用以下内容生成了授权令牌:

https://accounts.google.com/o/oauth2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&
response_type=code&
client_id=812741506391-h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com

这遵循以下说明:https ://developers.google.com/bigquery/authorization

4

2 回答 2

1

我不熟悉授权标头的内容,但我不确定您是否正确传递了 OAuth 令牌。当您运行 bq 客户端时,它会将 OAUth2 刷新令牌转换为访问令牌并将其传递给服务。据我所知,如果您传递原始刷新令牌,那么在不将其转换为短期访问令牌的情况下,这对于 api 访问是不可接受的。

您是否有不想使用 BigQuery Java 客户端的原因?(此处用于查询调用的 javadoc,用于查询 java 示例的 bigquery 文档在此处。)

于 2013-07-11T19:55:06.840 回答
0

这就是我在 Java 中使用服务帐户获得凭据的方式:

GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(new NetHttpTransport())
    .setJsonFactory(new JacksonFactory())
    .setServiceAccountId(properties.getProperty("SERVICE_ACCOUNT"))
    .setServiceAccountScopes(Arrays.asList(new String[] {"https://www.googleapis.com/auth/bigquery"}))
    .setServiceAccountPrivateKeyFromP12File(new File(properties.getProperty("P12_KEY")))
    .build();

这样,您就可以构建一个 BigQuery 服务对象:

BigQuery bigquery = Bigquery.Builder(
   new NetHttpTransport(), new JacksonFactory(), credential).setApplicationName(
    "BigQuery-Service-Accounts/0.1").setHttpRequestInitializer(credential).build();

使用服务对象,您可以运行典型的作业:

bigquery.jobs().query(...)

您是否有任何理由要手动执行 POST 请求?

于 2013-07-11T23:17:53.747 回答