Отправка запроса HTTP DELETE в Android
Мой клиентский API указывает, что для удаления объекта необходимо отправить запрос DELETE, содержащий данные заголовка Json, описывающие содержимое. Фактически это тот же вызов, что и добавление объекта, который выполняется через POST. Это работает отлично, кишки моего кода ниже:
HttpURLConnection con = (HttpURLConnection)myurl.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setUseCaches(false);
con.connect();
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(data); // data is the post data to send
wr.flush();
Чтобы отправить запрос на удаление, я изменил метод запроса на "УДАЛИТЬ" соответственно. Однако я получаю следующую ошибку:
java.net.ProtocolException: DELETE does not support writing
Итак, мой вопрос: как мне отправить запрос DELETE, содержащий данные заголовка из Android? Мне не хватает точки - можете ли вы добавить данные заголовка в запрос DELETE? Спасибо.
Ответы
Ответ 1
Чтобы добавить закрытие этого вопроса, выяснилось, что нет поддерживаемого метода для отправки запроса HTTP DELETE, содержащего данные заголовка.
Решение заключалось в том, что клиент изменил свой API для принятия стандартного запроса GET, который указывал, что действие должно быть удаленным, содержащим идентификатор подлежащего удалению элемента.
http://clienturl.net/api/delete/id12345
Ответ 2
Проблематичная строка con.setDoOutput(true);
. Удаление, которое исправит ошибку.
Вы можете добавить заголовки запросов в DELETE, используя addRequestProperty
или setRequestProperty
, но вы не можете добавить тело запроса.
Ответ 3
getOutputStream() работает только с запросами, которые имеют тело, например POST. Используя его на запросах, которые не имеют тела, например DELETE, будут вызывать исключение ProtocolException. Вместо этого вы должны добавить свои заголовки с помощью addHeader() вместо вызова getOutputStream().
Ответ 4
Я знаю, что это немного поздно, но если кто-то падает на поиски в google, как я, я решил так:
conn.setRequestProperty("X-HTTP-Method-Override", "DELETE");
conn.setRequestMethod("POST");
Ответ 5
Попробуйте ниже метод вызова метода HttpDelete, он работает для меня, надеясь, что работа для вас также
String callHttpDelete(String url){
try {
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 15000);
HttpConnectionParams.setSoTimeout(httpParams, 15000);
//HttpClient httpClient = getNewHttpClient();
HttpClient httpClient = new DefaultHttpClient();// httpParams);
HttpResponse response = null;
HttpDelete httpDelete = new HttpDelete(url);
response = httpClient.execute(httpDelete);
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.v(tag, "Yo! Response recvd ["+s.toString()+"]");
return s.toString();
} catch (Exception e){
e.printStackTrace();
}
return s.toString();
}
Ответ 6
Это ограничение HttpURLConnection
, на старых версиях Android (< = 4.4).
В то время как вы можете использовать HttpClient
, я не рекомендую его, поскольку это старая библиотека с несколькими проблемами, которые были удалены с Android 6.
Я бы рекомендовал использовать новую новую библиотеку, например OkHttp:
OkHttpClient client = new OkHttpClient();
Request.Builder builder = new Request.Builder()
.url(getYourURL())
.delete(RequestBody.create(
MediaType.parse("application/json; charset=utf-8"), getYourJSONBody()));
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
String string = response.body().string();
// TODO use your response
} catch (IOException e) {
e.printStackTrace();
}
Ответ 7
Вы не можете использовать метод addHeader()
?
Ответ 8
Вот мой метод запроса Delete
.
Просто это запрос post
с дополнительным RequestProperty
connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
Ниже полный метод.
public void executeDeleteRequest(String stringUrl, JSONObject jsonObject, String reqContentType, String resContentType, int timeout) throws Exception {
URL url = new URL(stringUrl);
HttpURLConnection connection = null;
String urlParameters = jsonObject.toString();
try {
connection = (HttpURLConnection) url.openConnection();
//Setting the request properties and header
connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
connection.setRequestMethod("POST");
connection.setRequestProperty("User-Agent", USER_AGENT);
connection.setRequestProperty(CONTENT_TYPE_KEY, reqContentType);
connection.setRequestProperty(ACCEPT_KEY, resContentType);
connection.setReadTimeout(timeout);
connection.setConnectTimeout(defaultTimeOut);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
responseCode = connection.getResponseCode();
// To handle web services which server responds with response code
// only
try {
response = convertStreamToString(connection.getInputStream());
} catch (Exception e) {
Log.e(Log.TAG_REST_CLIENT, "Cannot convert the input stream to string for the url= " + stringUrl + ", Code response=" + responseCode + "for the JsonObject: " + jsonObject.toString(), context);
}
} catch (
Exception e
)
{
if (!BController.isInternetAvailable(context)) {
IntentSender.getInstance().sendIntent(context, Constants.BC_NO_INTERNET_CONNECTION);
Log.e(Log.TAG_REST_CLIENT, "No internet connection", context);
}
Log.e(Log.TAG_REST_CLIENT, "Cannot perform the POST request successfully for the following URL: " + stringUrl + ", Code response=" + responseCode + "for the JsonObject: " + jsonObject.toString(), context);
throw e;
} finally{
if (connection != null) {
connection.disconnect();
}
}
}
Я надеюсь, что это помогло.
Ответ 9
Запрос DELETE является расширенной формой запроса GET, согласно документации по Android, которую вы не можете записать в теле запроса DELETE.
HttpUrlConnection будет " неспособен писать исключение протокола".
Если вы все еще хотите записать параметр в теле, я предлагаю вам использовать библиотеку OKHttp.
Документация OKHttp
Если вас интересует более простая библиотека, вы можете попробовать
Библиотека SimpleHttpAndroid
Здесь нужно помнить, что вы ничего не пишете в теле, а затем удалите строку
conn.setDoOutput(true);
Спасибо, надеюсь, это может помочь.