2

这与另一个关于 URL 缩短器的问题有关。URL 缩短器的代码在独立 Java 和 Android 上都可以正常工作。但是,当重新使用此代码与自定义 Google App Engine 应用程序通信时,该代码在独立 Java 上运行良好,但在 Android 上使用时会产生一个空的 self.request.body。为什么?

要重现此行为,请在 android 上运行以下代码,一次使用 Google 缩短 URL: https://www.googleapis.com/urlshortener/v1/url,一次使用指向 Web 服务器的自定义 URL。在两种情况下,独立 java 上的相同代码会产生完全相同的请求(如预期的那样)。在 Android 上,在自定义 URL 的情况下,内容正文为空且未设置 content-length。我正在使用杰克逊 1.7.1 运行 google-api-java-client 1.2.2-alpha。

代码片段:

    HttpTransport transport = GoogleTransport.create();
    HttpRequest request = transport.buildPostRequest();

    // Change this URL below from Google Shortener URL, to a custom URL,
    // and the code on Android produces an empty body and Content-Length is not set
    request.setUrl("GoogleAppEngine url goes here");

    JsonCContent content = new JsonCContent();
    GenericData data = new GenericData();
    data.put("id", "whatever");
    content.data = data;
    request.content = content;
    HttpResponse response = request.execute();
4

1 回答 1

2

我做了一些调试,结果是这样的:

  • 默认情况下,Android 上的实现选择 Apache HTTP 客户端进行低级传输。那里的代码是最低限度的,它看起来好像没有正确设置请求的 Content-Type 和 Content-Length。请求出去了,但是,一些(大多数)挑剔的 Web 服务器跳过了正文。谷歌网络服务器似乎处理得很好。因此,它似乎适用于 Google 服务器,但不适用于其他 Web 服务器(这有点奇怪,但是,这超出了我的问题的重点)。

  • 默认情况下,在 Java 上,选择 java.net.HttpURLConnection 用于低级 http 传输。这个实现更加冗长,并且整齐地设置了所有必需的字段。Content-Length 在那里,Content-Type 和所有其他字段也在那里。JSON 内容被序列化,所有的网络服务器都很高兴。包括我的自定义 GAE 应用程序。

因此,在 Android 上,以下解决方法可以解决问题:

拨打以下电话:

HttpTransport.setLowLevelHttpTransport(new com.google.api.client.javanet.NetHttpTransport());

在你做之前request.execute()

这样,在 Android 上,您将使用实际有效的传输(形成更整洁的请求)。

附言。正如生活中经常发生的那样,我变得懒惰,提出问题,希望有人为我解决。最终自己调试并解决了它,加上必须写所有这些。额外的工作 - 但我想,对于其他所有人来说都是有益的。希望其他人会发现它有用。

ps.2。google api java 客户端现在摇摇欲坠;)感谢作者的出色工作。

于 2011-01-30T18:33:06.497 回答