【问题标题】:Connect to Azure DocumentDB from Android从 Android 连接到 Azure DocumentDB
【发布时间】:2015-02-22 05:17:03
【问题描述】:

有没有人体验过从 android 连接到 Azure 的 documentdb?我已经尝试使用新的 Java SDK,但是由于核心 android SDK 中一些旧的所需 Apache 依赖冲突,它似乎在 android 中不受支持。我正在尝试使用 Rest API 方法,但速度很慢。

提前感谢您的帮助!

【问题讨论】:

    标签: android azure azure-cosmosdb


    【解决方案1】:

    好的,这是一个需要解决的噩梦。九小时后……-_-'。长话短说,这里有一些实际上可以成功运行的代码。这段代码并不完美,依赖于Retrofit

    首先,这是 Retrofit 中的示例“服务”接口:

    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 标头而不是日期标头。当前版本的 Azure DocumentDB 存在一个错误,似乎使生成的令牌无法正确授权。

    我希望这会有所帮助,并为您节省一些时间。

    【讨论】:

    • 早安,@jdscolam。你能帮我解决我的 SO 问题here 中非常相似的问题吗?
    • 你升级到使用retrofit2了吗? API似乎有所不同。例如 RestAdapter 类似乎不存在。
    • @Uberbug 很遗憾没有,而且我无法再访问代码库了。如果你想出一个解决方案,请分享它:)。
    • 我一直在破解它,我很快就会分享一些东西。
    猜你喜欢
    • 2017-12-30
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 2021-02-14
    • 2019-11-08
    • 2019-09-14
    • 2022-06-27
    • 2017-11-26
    相关资源
    最近更新 更多