从 Android 连接到 Azure DocumentDB

4

有没有人尝试过在Android上连接Azure的DocumentDB?我已经尝试使用新的Java SDK,但由于核心Android SDK中一些旧的必需的Apache依赖项冲突问题,它似乎不支持Android。我正在尝试使用Rest API方法,但进展缓慢。

非常感谢任何帮助!

1个回答

6

好的,这个问题解决起来真是一场噩梦。九个小时后……-_-。长话短说,这里有一些代码可以成功运行。这段代码并不完美,并且依赖于Retrofit

首先,这是一个在Retrofit中的示例“Service”接口:

import retrofit.Callback;
import retrofit.http.Body;
import retrofit.http.Header;
import retrofit.http.POST;

public interface MyPojoService {
    @POST("/dbs/[db_id]/colls/[collection_id]/docs")
    void addDocument(@Header("authorization") String authorization, @Header("x-ms-date") String date, @Body MyPojo myPojo, Callback<MyPojo> cb);
}

接下来,我们有一个类内的初始设置字段,将调用DocumentDB:
// Replace with your DocumentDB master key.
private static final String MASTER_KEY = "[Insert Key Here]";

//Gson instance.
private Gson gson = new Gson();

现在我们将拥有一个针对RESTful端点执行的方法:
public void callDocumentDB() {
    SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
    String headerDate = formatter.format(new Date()).toLowerCase();  //According to the spec the format matters here.  Make sure to use this format on the header dates.


    MyPojo myPojo = new MyPojo();
    myPojo.id = UUID.randomUUID().toString(); //This is the only required field, and does not have to be a UUID.

    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("https://[INSERT DB NAME HERE].documents.azure.com")
            .build();

    MyPojoService service = restAdapter.create(MyPojoService.class);

    service.addDocument(generateAuthHeader("post", "docs", "[INSERT COLLECTION ID HERE]", headerDate, MASTER_KEY), headerDate, myPojo, new Callback<MyPojo>() {
        @Override
        public void success(MyPojo myPojo, Response response) {
            //[INSERT API SUCCESSFUL CALL LOGIC HERE]
        }

        @Override
        public void failure(RetrofitError error) {
            throw error;
        }
    });
}

最后我们有一个生成授权头的方法。这个方法在编写时非常困难,但它按照规范正常工作。
private String generateAuthHeader(String verb, String resourceType, String resourceId, String date, String masterKeyBase64) throws Exception
{
    //Decode the master key, and setup the MAC object for signing.
    byte[] masterKeyBytes = Base64.decode(masterKeyBase64, Base64.NO_WRAP);
    Mac mac = Mac.getInstance("HMACSHA256");
    mac.init(new SecretKeySpec(masterKeyBytes, "HMACSHA256"));

    //Build the unsigned auth string.
    String stringToSign = verb + "\n"
            + resourceType + "\n"
            + resourceId + "\n"
            + date + "\n"
            + "\n";

    //Sign and encode the auth string.
    String signature = Base64.encodeToString(mac.doFinal(stringToSign.toLowerCase().getBytes("UTF8")), Base64.NO_WRAP);

    //Generate the auth header.
    String authHeader = URLEncoder.encode("type=master&ver=1.0&sig=" + signature, "UTF8");

    return authHeader;
}

注意:请注意,generateAuthString和MyPojoService已设置为使用x-ms-date标头而不是date标头。当前版本的Azure DocumentDB存在错误,似乎会阻止生成的令牌正确授权。
我希望这可以帮助您节省一些时间。

你好,@jdscolam。能否帮我解决一个与我的SO问题在这里非常相似的问题? - Gregory Stein
你是否已经升级到使用Retrofit2了?API似乎有所不同。例如,RestAdapter类似乎不存在了。 - Uberbug
@Uberbug 很遗憾,我现在没有访问代码库的权限了。如果你有解决方案,请分享给我 :). - jdscolam
我一直在试着解决这个问题,很快我会有一些东西分享。 - Uberbug

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接