11

Galaxy Nexus が今日届きました。最初に行った作業の 1 つは、自分のアプリをその上にロードして、友人にデモンストレーションできるようにすることでした。その機能の一部には、Google リーダーからの RSS フィードのインポートが含まれます。ただし、これを試してみると、405 Method Not Allowed エラーが発生しました。

この問題は 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;
    }
}

この問題を引き起こしている可能性のあるものはありますか? この問題を回避するために、この関数をより適切にコーディングできますか?

よろしくお願いします。

4

5 に答える 5

20

この動作については、Android Developers: HttpURLConnectionで説明されています。

HttpURLConnection は、デフォルトで GET メソッドを使用します。setDoOutput(true) が呼び出された場合、POST が使用されます。

奇妙なことに、これは実際には 4.0 までの動作ではなかったため、既存の公開済みアプリの多くが機能しなくなるのではないかと思います。

Android 4.0 では、GET が POST に変わります。

于 2011-12-16T18:30:01.447 に答える
10

この行を削除するとうまくいきました:

connection.setDoOutput(true);

4.0 は、この行で間違いなく POST であると判断します。

于 2011-12-01T08:22:01.020 に答える
8

これを取り除きます:

connection.setRequestProperty("Content-Type","application/x-www-form-urlendcoded");

これは、これが POST であることを API に伝えます。

経由でどのように行うことができるかについての更新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();
    }
}
于 2011-11-18T18:29:19.573 に答える
3

これは私が得たものです-基本的に setDoOutput(true) を設定することにより、これが setRequestMethod で GET であることを指定した場合でも、接続を確立するときに POST 要求が強制されます。

HttpURLConnection は、デフォルトで GET メソッドを使用します。setDoOutput(true) が呼び出された場合、POST が使用されます。その他の HTTP メソッド (OPTIONS、HEAD、PUT、DELETE、および TRACE) は setRequestMethod(String) で使用できます。

これはしばらく前に私を捕まえました-非常にイライラします...

http://developer.android.com/reference/java/net/HttpURLConnection.htmlを参照して、HTTP メソッドの見出しに移動します

于 2012-08-28T08:45:52.353 に答える
2

以前の ICS では、Content-Length 値を指定せずに本文のない POST を作成することで回避できることがわかりましたが、ICS 後では Content-Length: 0 を設定する必要があります。

于 2012-01-10T06:02:35.460 に答える