在Appengine中使用JSON Api为Google存储对象设置ACL

时间:2012-11-30 01:58:53

标签: google-app-engine google-cloud-storage

我想使用appengine中的Json API将ACL添加到Google Storage对象。我已经尝试了以下代码,但是我得到了400响应而没有详细信息。我没有使用java-client-libraries,但是我愿意尝试。以下是我的代码:

public static void updateACL(String bucket, String object,
        List<String> emails) {

    try {
        ArrayList scopes = new ArrayList();
        scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
        AppIdentityService appIdentity = AppIdentityServiceFactory
                .getAppIdentityService();
        AppIdentityService.GetAccessTokenResult accessToken = appIdentity
                .getAccessToken(scopes);
        // The token asserts the identity reported by
        // appIdentity.getServiceAccountName()
        logger.log(Level.WARNING, "bucket: "+bucket+" object: "+object+ " email: "+emails.get(0));
        JSONObject request = new JSONObject();
        request.put("entity", "user-" + emails.get(0));
        request.put("roles", "READER");

        URL url = new URL("https://www.googleapis.com/storage/v1beta1/b/"
                + bucket + "/o/"+object+"/acl?key=" + API_KEY);
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.addRequestProperty("Content-Type", "application/json");
        connection.addRequestProperty("Authorization", "OAuth "
                + accessToken.getAccessToken());
        String urlParameters = "bucket=" + bucket + "&object=" + object;
        OutputStreamWriter writer = new OutputStreamWriter(
                connection.getOutputStream());
        request.write(writer);
        writer.close();
        logger.log(Level.WARNING, connection.getResponseMessage());
        logger.log(Level.WARNING,
                String.valueOf(connection.getResponseCode()));
        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            // Note: Should check the content-encoding.
            // JSONTokener response_tokens = new
            // JSONTokener(connection.getInputStream());
            // JSONObject response = new JSONObject(response_tokens);
            // return (String) response.get("id");
            return;
        } else {

        Scanner s;
        s = new Scanner(connection.getErrorStream());
        s.useDelimiter("\\Z");
        String response = s.next();
        s.close();
            throw new Exception(connection.getResponseCode()+" "+connection.getResponseMessage()+
                    response);
        }
    } catch (Exception e) {

        logger.log(Level.WARNING, "exception: "+e.getMessage());

    }
}

我得到的回复是400,但细节根本没用。

  

“错误”:{     “错误”:[      {       “域名”:“全球”,       “理由”:“必需”,       “消息”:“必填”      }     ]     “代码”:400,     “消息”:“必填”    }   }

1 个答案:

答案 0 :(得分:4)

我怀疑你的代码中有一两个小错误。在这个特定的实例中,当JSON api期望角色时,它看起来像是在发送角色。

我认为有助于调试的一件事是将我的代码通过网络发送的内容与Google APIs explorer生成的HTTP请求进行比较。

  1. 导航至https://developers.google.com/storage/docs/json_api/v1/objectAccessControls/insert
  2. 开启Authorize requests using OAuth 2.0按钮。
  3. 设置bucketobjectentityrole字段。
  4. 点击执行。
  5. 您应该看到生成的HTTP请求和响应。

    请求:

    POST https://www.googleapis.com/storage/v1beta1/b/bucket/o/obj/acl?key={YOUR_API_KEY}
    
    Content-Type:  application/json
    Authorization:  Bearer ya29.1111111111111111111111111111111111-aaaaaaaaaaaaa
    X-JavaScript-User-Agent:  Google APIs Explorer
    
    {
     "entity": "user-person@example.com",
     "role": "READER"
    }
    

    响应:

    200 OK
    
    - Hide headers -
    
    cache-control:  no-cache, no-store, max-age=0, must-revalidate
    content-type:  application/json; charset=UTF-8
    date:  Fri, 30 Nov 2012 02:16:57 GMT
    etag:  "fP_WVz7o95h5w16zKezUFJzMmHg/6CyL8wOk_60IJhaxNewPk1fHpQo"
    expires:  Fri, 01 Jan 1990 00:00:00 GMT
    server:  GSE
    
    {
    
     "kind": "storage#objectAccessControl",
     "id": "bucket/obj/user-person@example.com",
     "selfLink": "https://www.googleapis.com/storage/v1beta1/b/bucket/o/obj/acl/user-person@example.com",
     "bucket": "bucket",
     "object": "obj",
     "entity": "user-person@example.com",
     "role": "READER",
     "email": "person@example.com"
    }
    

    现在确保通过网络发送的请求看起来与此相同。