webentwicklung-frage-antwort-db.com.de

Senden einer HTTP DELETE-Anfrage in Android

Die API meines Kunden gibt an, dass zum Entfernen eines Objekts eine DELETE-Anforderung gesendet werden muss, die Json-Header-Daten enthält, die den Inhalt beschreiben. Eigentlich ist es derselbe Aufruf wie das Hinzufügen eines Objekts, was über POST erfolgt. Dies funktioniert gut, die Eingeweide meines Codes sind unten:

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

Um die Löschanforderung zu senden, habe ich die Anforderungsmethode entsprechend in "DELETE" geändert. Ich erhalte jedoch den folgenden Fehler:

Java.net.ProtocolException: DELETE does not support writing

Meine Frage ist also, wie sende ich eine DELETE-Anfrage mit Header-Daten von Android? Fehlt mir der Punkt - können Sie einer DELETE-Anfrage Header-Daten hinzufügen? Vielen Dank.

24
androidneil

Die problematische Linie ist con.setDoOutput(true);. Wenn Sie das entfernen, wird der Fehler behoben.

Sie können einem DELETE Anforderungsheader hinzufügen, indem Sie addRequestProperty oder setRequestProperty verwenden, aber Sie können keinen Anforderungshauptteil hinzufügen.

30
TalkLittle

Ich weiß, es ist ein bisschen spät, aber wenn jemand hier auf der Suche nach Google wie ich stürzt, habe ich das folgendermaßen gelöst:

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

getOutputStream () funktioniert nur bei Anfragen mit einem Body wie POST. Wenn Sie es für Anforderungen verwenden, die keinen Body haben, wie z. B. DELETE, wird eine ProtocolException ausgelöst. Stattdessen sollten Sie Ihre Header mit addHeader () hinzufügen, anstatt getOutputStream () aufzurufen.

4
Bruno Oliveira

Dies ist eine Einschränkung von HttpURLConnection bei alten Android-Versionen (<= 4.4).

Sie könnten alternativ auch HttpClient verwenden, ich empfehle es jedoch nicht, da es sich um eine alte Bibliothek mit mehreren Problemen handelt, die aus Android 6 entfernt wurde.

Ich würde empfehlen, eine neue Bibliothek wie OkHttp zu verwenden:

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

Probieren Sie die folgende Methode aus, um die HttpDelete-Methode aufzurufen. Sie funktioniert für mich und hofft, dass sie auch für Sie funktioniert

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

Die DELETE-Anforderung ist eine erweiterte Form der GET-Anforderung, da Sie gemäß der Android-Dokumentation nicht in den Text der DELETE-Anforderung schreiben können. HttpUrlConnection löst " Protokollausnahme kann nicht geschrieben werden " aus.

Wenn Sie den Parameter dennoch in den Body schreiben möchten, empfehle ich Ihnen, die OKHttp Library zu verwenden.

OKHttp Dokumentation

Wenn Sie daran interessiert sind, eine einfachere Bibliothek zu verwenden, können Sie versuchen, SimpleHttpAndroid library

Eine Sache, an die Sie sich erinnern sollten, ist, wenn Sie nichts in den Körper schreiben, dann entfernen Sie die Linie

conn.setDoOutput(true);

Danke, hoffentlich kann es helfen.

2
yubaraj poudel

Hier ist meine Delete Anforderungsmethode.

Einfach ist es post Anfrage mit extra RequestProperty

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

Nachfolgend die vollständige Methode.

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

}

Ich hoffe es hat geholfen.

0
Sami Eltamawy

Sie können nicht einfach die Methode addHeader() verwenden?

0
hwrdprkns