web-dev-qa-db-fra.com

Envoi de la requête HTTP DELETE sous Android

L'API de mon client spécifie que pour supprimer un objet, une demande DELETE doit être envoyée, contenant les données d'en-tête Json décrivant le contenu. Effectivement, c'est le même appel que d'ajouter un objet, via POST. Cela fonctionne bien, les entrailles de mon code est ci-dessous:

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();

Pour envoyer la demande de suppression, j'ai modifié la méthode de demande en "DELETE" en conséquence. Cependant, j'obtiens l'erreur suivante:

Java.net.ProtocolException: DELETE does not support writing

Ma question est donc la suivante: comment envoyer une demande DELETE contenant des données d’en-tête à partir d’Android? Est-ce que je manque le point - pouvez-vous ajouter des données d'en-tête à une demande DELETE? Merci.

24
androidneil

La ligne problématique est con.setDoOutput(true);. Supprimer cela va corriger l'erreur.

Vous pouvez ajouter des en-têtes de requête à un objet DELETE à l'aide de addRequestProperty ou setRequestProperty, mais vous ne pouvez pas ajouter de corps de requête.

30
TalkLittle

Je sais que c'est un peu tard, mais si quelqu'un tombe ici en cherchant sur google comme moi, je résous de cette façon:

    conn.setRequestProperty("X-HTTP-Method-Override", "DELETE");
    conn.setRequestMethod("POST");
4
jos

getOutputStream () ne fonctionne que sur les requêtes ayant un corps, comme POST. Son utilisation sur des requêtes sans corps, comme DELETE, lève une exception ProtocolException. Au lieu de cela, vous devriez ajouter vos en-têtes avec addHeader () au lieu d'appeler getOutputStream ().

4
Bruno Oliveira

Il s'agit d'une limitation de HttpURLConnection, sur les anciennes versions d'Android (<= 4.4).

Bien que vous puissiez également utiliser HttpClient, je ne le recommande pas car c'est une ancienne bibliothèque avec plusieurs problèmes qui était - supprimé d'Android 6 .

Je recommanderais d'utiliser une nouvelle bibliothèque récente comme 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();
}
3
Murphy

Essayez la méthode ci-dessous pour la méthode d'appel HttpDelete, cela fonctionne pour moi, en espérant que cela fonctionne également pour vous.

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();
        }
2
Lokesh

La requête DELETE est une forme étendue de requête GET, conformément à la documentation Android que vous ne pouvez pas écrire dans le corps de la requête DELETE. HttpUrlConnection lancera " impossible d'écrire une exception de protocole ".

Si vous voulez toujours écrire le paramètre dans le corps, je vous suggère d'utiliser le OKHttp Library.

Documentation OKHttp

Si vous souhaitez utiliser une bibliothèque plus simple, vous pouvez essayer bibliothèque SimpleHttpAndroid

Une chose à retenir ici est que si vous n’écrivez rien dans le corps, supprimez la ligne.

conn.setDoOutput(true);

Merci, j'espère que cela peut aider.

2
yubaraj poudel

Voici ma méthode de requête Delete.

Il s’agit simplement d’une requête post avec RequestProperty supplémentaire

connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");

Ci-dessous la méthode complète.

    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();
        }
    }

}

J'espère que ça a aidé.

0
Sami Eltamawy

Vous ne pouvez pas simplement utiliser la méthode addHeader() ?

0
hwrdprkns