HttpDelete avec le corps

j'essaie d'utiliser un objet HttpDelete pour invoquer la méthode de suppression d'un service web. Le code du service Web analyse JSON du corps du message. Cependant, je ne comprends pas comment ajouter un corps à un objet HttpDelete. Est-il un moyen de faire cela?

avec HttpPut et HttpPost, j'appelle la méthode setEntity et je passe dans mon JSON. Il ne semble pas y avoir une telle méthode pour HttpDelete.

S'il n'y a aucun moyen de HttpDelete objet, pourriez-vous me relier à une ressource qui utilise une super classe de HttpDelete telle que je puisse définir la méthode (supprimer) et définir un corps. Je sais que ce n'est pas idéal, mais je ne peux pas modifier le service web.

40
demandé sur Brian Tompsett - 汤莱恩 2010-09-23 00:25:55

5 réponses

avez-vous essayé de remplacer HttpEntityEnclosingRequestBase comme suit:

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import java.net.URI;
import org.apache.http.annotation.NotThreadSafe;

@NotThreadSafe
class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
    public static final String METHOD_NAME = "DELETE";
    public String getMethod() { return METHOD_NAME; }

    public HttpDeleteWithBody(final String uri) {
        super();
        setURI(URI.create(uri));
    }
    public HttpDeleteWithBody(final URI uri) {
        super();
        setURI(uri);
    }
    public HttpDeleteWithBody() { super(); }
}

qui va créer un HttpDelete - lookalike qui a une méthode setEntity . Je pense que la classe abstraite fait presque tout pour vous, donc c'est peut-être tout ce dont vous avez besoin.

FWIW, le code est basé sur cette source pour HttpPost que Google a tourné .

91
répondu Walter Mundt 2010-09-29 10:09:16

suivant les conseils de Walter Mudnt, vous pouvez utiliser ce code. Il fonctionne, juste fait tout en testant mon rest webservice.

try {
        HttpEntity entity = new StringEntity(jsonArray.toString());
        HttpClient httpClient = new DefaultHttpClient();
        HttpDeleteWithBody httpDeleteWithBody = new HttpDeleteWithBody("http://10.17.1.72:8080/contacts");
        httpDeleteWithBody.setEntity(entity);

        HttpResponse response = httpClient.execute(httpDeleteWithBody);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

pour accéder à la réponse, vous pouvez simplement faire: response.getStatusLine();

9
répondu dazito 2014-04-10 10:03:07

la question de savoir si l'organisme est autorisé ou non dans la demande HTTP DELETE fait l'objet d'une interprétation différente. Voir ce par exemple. Dans la spécification HTTP 1.1 elle n'est pas explicitement interdite. À mon avis, vous ne devrait pas utiliser le corps dans le HTTP DELETE .

néanmoins je pense que vous devriez utiliser URL comme mysite/myobject/objectId ( shop.com/order/1234 ) où le objectId ( une partie de l'url ) est l'information supplémentaire. Comme alternative, vous pouvez utiliser paramètres D'URL : mysite/myobject?objectName=table&color=red pour envoyer des informations supplémentaires au serveur dans la requête HTTP DELETE . La partie commençant avec"?'est le urlencoded paramètres décidé dy '&'.

si vous voulez envoyer des informations plus complexes, vous pouvez convertir les données à JSON avec respect de DataContractJsonSerializer ou JavaScriptSerializer et ensuite envoyer les données converties (une chaîne que je nomme myJsonData plus tard) aussi comme le paramètre: mysite/myobject?objectInfo=myJsonData .

si vous avez besoin d'envoyer trop de données supplémentaires dans le cadre de la demande HTTP DELETE de sorte que vous avez des problèmes avec la longueur D'URL, alors vous devriez probablement mieux modifier la conception de votre application.

mise à JOUR Vous pouvez le faire par exemple comme suit

// somewhere above add: using System.Net; and using System.IO;

WebClient myWebClient = new WebClient ();

// 1) version: do simple request    
string t= myWebClient.UploadString ("http://www.examples.com/", "DELETE", "bla bla");
// will be send following:
//
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Expect: 100-continue
// Connection: Keep-Alive
//
//bla bla

// 2) version do complex request    
Stream stream = myWebClient.OpenWrite ("http://www.examples.com/", "DELETE");

string postData = "bla bla";
byte[] myDataAsBytes = Encoding.UTF8.GetBytes (postData);
stream.Write (myDataAsBytes, 0, myDataAsBytes.Length);
stream.Close (); // it send the data
// will be send following:
// 
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Expect: 100-continue
// 
// bla bla

// 3) version
// create web request 
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create ("http://www.examples.com/");
webRequest.Method = "DELETE";
webRequest.ServicePoint.Expect100Continue = false;

// post data 
Stream requestStream = webRequest.GetRequestStream ();
StreamWriter requestWriter = new StreamWriter (requestStream);
requestWriter.Write (postData);
requestWriter.Close ();

//wait for server response 
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse ();
// send following:
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Connection: Keep-Alive
// 
// bla bla

le code complet pourrait être un peu plus complexe, mais il fonctionne. Néanmoins, je continue à dire que le Service Web avait besoin de données dans le corps de la requête HTTP DELETE est mal conçu.

4
répondu Oleg 2017-05-23 12:10:30

utilisez ceci,

class MyDelete extends HttpPost{
    public MyDelete(String url){
        super(url);
    }
    @Override
    public String getMethod() {
        return "DELETE";
    }
}
3
répondu Ishan Liyanage 2013-06-06 10:19:10

en rénovation

import okhttp3.Request;

private final class ApiInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request oldRequest = chain.request();
        Request.Builder builder = oldRequest.newBuilder();
        if(condition) {
            return chain.proceed(builder.build().newBuilder().delete(builder.build().body()).build());
        }
        return chain.proceed(builder.build());
    }
}

vous devez déclencher la condition, via quelque chose et éventuellement faire un certain filtrage pour l'url / en-tête / corps pour supprimer le déclencheur,

sauf si l'url de suppression/corps/en-tête est suffisamment unique pour ne pas entrer en collision avec des requêtes post ou get.

0
répondu HopefullyHelpful 2017-01-06 15:24:25