Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;411所需长度“-来自使用Android Api 10及以下版本的Google Docs Api的响应_Android_Google Api_Google Docs Api_Fragmentation_Google Api Java Client - Fatal编程技术网

&引用;411所需长度“-来自使用Android Api 10及以下版本的Google Docs Api的响应

&引用;411所需长度“-来自使用Android Api 10及以下版本的Google Docs Api的响应,android,google-api,google-docs-api,fragmentation,google-api-java-client,Android,Google Api,Google Docs Api,Fragmentation,Google Api Java Client,我正在为Android设备开发一个应用程序,其中一个部分是在用户Google Docs和设备存储之间实现下载和上传。我遇到的问题是,我在不同版本的Android API之间获得了不同的行为。我一直在APIL10(Android 2.3.3)上进行大部分开发。在虚拟设备上没有问题(我没有使用此API lvl或更高版本测试的真实设备)。在API lvl 8(2.2.x)及以下版本的设备和模拟器上,当请求启动可恢复上传会话时,我遇到了Google Docs API要求的411长度错误。在API lvl

我正在为Android设备开发一个应用程序,其中一个部分是在用户Google Docs和设备存储之间实现下载和上传。我遇到的问题是,我在不同版本的Android API之间获得了不同的行为。我一直在APIL10(Android 2.3.3)上进行大部分开发。在虚拟设备上没有问题(我没有使用此API lvl或更高版本测试的真实设备)。在API lvl 8(2.2.x)及以下版本的设备和模拟器上,当请求启动可恢复上传会话时,我遇到了Google Docs API要求的411长度错误。在API lvl 10的emulator上运行相同的应用程序时不会发生这种情况

我正在使用Eclipse进行开发,并使用Google API Java Client 1.4.1-beta与Docs API进行通信。以下是我为Google Docs API提供的文档:

根据上述文件,启动一个可恢复的上传会话就是发送一个空的POST请求。谷歌文档用户的“根”地址为“”。以下是我为(空体)请求设置头的方式:

我还应该提到,我用于HTTP的库如下所示:

com.google.api.client.googleapis.GoogleHeaders;
com.google.api.client.http.HttpRequest;
com.google.api.client.http.HttpRequestFactory;
com.google.api.client.http.HttpRequestInitializer;
com.google.api.client.http.HttpTransport;
com.google.api.client.http.HttpResponse;
com.google.api.client.http.HttpContent;
com.google.api.client.http.javanet.NetHttpTransport;
我做了一些数据包嗅探来实际查看标题,瞧,在不同版本的Android上,标题的设置方式实际上并不相同。如果您注意到,默认情况下,请求应该使用https发送,因此我将其更改为使用http查看数据包中的头。结果如下:

使用Android API第10级仿真器:

POST /feeds/upload/create-session/default/private/full?convert=false HTTP/1.1
Accept-Encoding: gzip
Authorization: **REMOVED**
Content-Length: 0
Content-Type: text/plain
GData-Version: 3
Slug: 5mbfile.txt
User-Agent: test Google-API-Java-Client/1.4.1-beta
X-Upload-Content-Length: 5242880
X-Upload-Content-Type: text/plain
Host: docs.google.com
Connection: Keep-Alive
使用API lvl 7的仿真器:

POST /feeds/upload/create-session/default/private/full?convert=false HTTP/1.1
accept-encoding: gzip
authorization: **REMOVED**
content-type: text/plain
gdata-version: 3
slug: 5mbfile.txt
user-agent: test Google-API-Java-Client/1.4.1-beta
x-upload-content-length: 5242880
x-upload-content-type: text/plain
Host: docs.google.com
Connection: Keep-Alive
请注意缺少内容长度标题,情况也不同。这就解释了为什么我会得到411响应,但如何解决这个问题呢?显然,我的目标是在所有设备上获得相同的行为(由于与此问题无关的原因,Android 1.x除外),最好不要使用特定版本的代码

老实说,我想不出有多少适合我的代码的解决方案。我唯一能想到的是:

transport = new NetHttpTransport();
transport.defaultHeaders.contentLength = Integer.toString(0);
在API中使用(不推荐使用的)方法以不同方式设置标头,但没有效果。请求中的实际标头仍然相同

将属性设置为“0”或Integer.toString(0)也没有什么区别(显然,我在这里有点绝望)

因此,任何旨在找到解决方案的帮助或建议都是非常受欢迎的。如果特别要求,我将提供更多代码,并且包嗅探可以测试不同的解决方案。这也很可能是谷歌Api Java客户端或Android中的一个bug。但是哪一个呢?如果找不到解决方案,我对安卓系统的了解还不够深入,不知道在哪里报告这个(可疑的)bug。因此,如果您怀疑罪魁祸首确实不是我的代码,那么请分享您对哪个组件导致以不同方式设置头的想法

编辑-Algo请求堆栈跟踪,如下所示:

编辑-我正在为内容设置一个mimetype,尽管主体是空的。我尝试删除内容类型标题,但没有改进。这一行现在在上面的代码中被注释掉了

编辑-我一直在尝试解决这个问题。这是在同一代码中尝试以两种不同方式设置标头时的堆栈跟踪:


同时使用时,它们会相互碰撞。删除其中任何一个都会产生与以前类似的结果(文档需要411个长度,请求中没有内容长度)。使用其中一种方法和不推荐的方法(transport.defaultHeaders.contentLength=“0”)创建请求时,不会发生冲突(或不会显示在堆栈跟踪中)。使用上述任何方法的任何组合,都可能出现双头冲突或请求没有内容长度。

您可以尝试在Android环境中使用ApacheHttpTransport,而不是NetHttpTransport。NetHttpTransport有几个问题,包括您在这里遇到的问题,特别是2.3之前的问题

根据javadocs:

从SDK 2.3开始,强烈建议使用com.google.api.client.javanet.NetHttpTransport。他们的Apache HTTP客户端实现没有得到很好的维护

对于SDK 2.2及更早版本,不建议使用com.google.api.client.apache.ApacheHttpTransport com.google.api.client.javanet.NetHttpTransport,因为HttpURLConnection的Android SDK实现中存在一些错误

我一直在安卓2.3环境中使用ApacheHttpTransport,没有任何问题。如果您希望支持多个API级别,并希望遵循javadocs中的指导原则,则需要实现某种工厂,该工厂能够根据代码运行的API级别提供正确的传输。

请改用此工厂:

HttpTransport transport = AndroidHttp.newCompatibleTransport();

这就是Google推荐的与所有API级别的兼容性,因为它根据API的版本选择了正确的实现。你不必自己实现这个。我已经对它进行了测试,它对2.2和2.3都有效。

应该有某种方法来禁用请求验证。如果您停止执行验证请求。它不会检查内容长度。Algo,我试图找到一种禁用请求验证的方法,但没有找到。验证是在谷歌端完成的,所以我真的无法控制验证。如果您知道有什么办法,请通知我,因为这样可以使应用程序正常工作。尽管这是一种有点“肮脏”的修复方法,但我很乐意现在就使用它。我认为您应该手动设置一些内容长度。或者请去谷歌论坛和报告是作为错误或任何我相信你会很快得到答复。请和我分享你的解决方案。我不明白你所说的“手动设置”内容长度是什么意思。我所知道的最手动的方式是
headers.contentLength = "0";
headers.set("Content-length", "0");
HttpTransport transport = AndroidHttp.newCompatibleTransport();