Android 4.0 ICS将HttpURLConnection GET请求转换为POST请求

Mic*_*odd 11 java android google-reader android-4.0-ice-cream-sandwich

我的Galaxy Nexus今天到了,我做的第一件事就是将我的应用程序加载到它上面,这样我就可以向朋友们展示它了.其部分功能涉及从Google阅读器导入RSS源.但是,在尝试这个时,我得到405方法不允许错误.

这个问题是Ice Cream Sandwich特有的.我附上的代码在Gingerbread和Honeycomb上运行良好.当GET请求神奇地变成POST请求时,我已经将错误追溯到建立连接的那一刻.

/**
 * Get the authentication token from Google
 * @param auth The Auth Key generated in getAuth()
 * @return The authentication token
 */
private String getToken(String auth) {
    final String tokenAddress = "https://www.google.com/reader/api/0/token";
    String response = "";
    URL tokenUrl;

    try {
        tokenUrl = new URL(tokenAddress);
        HttpURLConnection connection = (HttpURLConnection) tokenUrl.openConnection();

        connection.setRequestMethod("GET");
        connection.addRequestProperty("Authorization", "GoogleLogin auth=" + auth);
        connection.setRequestProperty("Content-Type","application/x-www-form-urlendcoded");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        Log.d(TAG, "Initial method: " + connection.getRequestMethod()); // Still GET at this point

        try {
            connection.connect();
            Log.d(TAG, "Connected. Method is: " + connection.getRequestMethod());  // Has now turned into POST, causing the 405 error
            InputStream in = new BufferedInputStream(connection.getInputStream());
            response = convertStreamToString(in);
            connection.disconnect();
            return response;

        }
        catch (Exception e) {
            Log.d(TAG, "Something bad happened, response code was " + connection.getResponseCode()); // Error 405
            Log.d(TAG, "Method was " + connection.getRequestMethod()); // POST again
            Log.d(TAG, "Auth string was " + auth);
            e.printStackTrace();
            connection.disconnect();
            return null;
        }
    }
    catch(Exception e) {
        // Stuff
        Log.d(TAG, "Something bad happened.");
        e.printStackTrace();
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么可能导致这个问题吗?这个功能可以更好地编码以避免这个问题吗?

提前谢谢了.

小智 20

Android开发人员中描述了此行为:HttpURLConnection

HttpURLConnection默认使用GET方法.如果调用了setDoOutput(true),它将使用POST.

但奇怪的是,直到4.0,这实际上并没有出现这种情况,所以我认为它会破坏许多现有的已发布应用程序.

Android 4.0上有更多内容,将GET转换为POST.


Fed*_*dor 10

删除此行对我有用:

connection.setDoOutput(true);
Run Code Online (Sandbox Code Playgroud)

4.0认为这一行绝对应该是POST.

  • 谢谢Fedor,它也为我工作.我对GET方法有同样的问题.当我用setDoOutPut(true)调用GET方法时,我收到了Http 405:Method Not Allowed消息.再次感谢. (2认同)

Vit*_*nko 8

摆脱这个:

connection.setRequestProperty("Content-Type","application/x-www-form-urlendcoded");
Run Code Online (Sandbox Code Playgroud)

这告诉API这是一个POST.

更新如何通过HttpClient以下方式完成:

String response = null;
HttpClient httpclient = null;
try {
    HttpGet httpget = new HttpGet(yourUrl);
    httpget.setHeader("Authorization", "GoogleLogin auth=" + auth);
    httpclient = new DefaultHttpClient();
    HttpResponse httpResponse = httpclient.execute(httpget);

    final int statusCode = httpResponse.getStatusLine().getStatusCode();
    if (statusCode != HttpStatus.SC_OK) {
        throw new Exception("Got HTTP " + statusCode 
            + " (" + httpResponse.getStatusLine().getReasonPhrase() + ')');
    }

    response = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);

} catch (Exception e) {
    e.printStackTrace();
    // do some error processing here
} finally {
    if (httpclient != null) {
        httpclient.getConnectionManager().shutdown();
    }
}
Run Code Online (Sandbox Code Playgroud)