Отправка запроса 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);

Спасибо, надеюсь, это может помочь.