Android 4.0 ICS превращает HttpURLConnection GET запросы в запросы POST

Моя Galaxy Nexus прибыла сегодня, и одна из первых вещей, которую я сделал, это загрузить мое приложение, чтобы я мог продемонстрировать это своим друзьям. Часть его функций включает импорт RSS-каналов из Google Reader. Однако при попытке этого я получал ошибки 405 Method Not Allowed.

Эта проблема связана с сандвичем с мороженым. Код, который я приложил, отлично работает на 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; } } 

Есть ли что-то, что может вызвать эту проблему? Может ли эта функция лучше кодироваться, чтобы избежать этой проблемы?

Спасибо заранее.

Solutions Collecting From Web of "Android 4.0 ICS превращает HttpURLConnection GET запросы в запросы POST"

Такое поведение описано в Android Developers: HttpURLConnection

HttpURLConnection использует метод GET по умолчанию. Он будет использовать POST, если был вызван setDoOutput (true).

Странно, однако, что это не было поведением до 4.0, поэтому я бы предположил, что это сломает многие существующие опубликованные приложения.

Более того, на Android 4.0 становится GET в POST .

Удаление этой строки работало для меня:

 connection.setDoOutput(true); 

4.0 думает, что эта строка обязательно должна быть POST.

Избавьтесь от этого:

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

Это говорит API, что это POST.

UPDATE о том, как это можно сделать с помощью 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(); } } 

Это то, что меня достало – в основном, установив setDoOutput (true), он вызывает запрос POST при создании соединения, даже если вы укажете, что это GET в setRequestMethod :

HttpURLConnection использует метод GET по умолчанию. Он будет использовать POST, если был вызван setDoOutput (true). Другие методы HTTP (OPTIONS, HEAD, PUT, DELETE и TRACE) могут использоваться с setRequestMethod (String).

Это застало меня некоторое время назад – очень расстраивающе …

См. http://developer.android.com/reference/java/net/HttpURLConnection.html и перейдите в раздел «Методы HTTP»

Я обнаружил, что pre-ICS может уйти с помощью без POST без предоставления значения Content-Length, однако после ICS вы должны установить Content-Length: 0.