HttpDelete с телом

Я пытаюсь использовать объект HttpDelete для вызова метода удаления веб-службы. Код веб-службы анализирует JSON из тела сообщения. Однако я не понимаю, как добавить тело в объект HttpDelete. Есть ли способ сделать это?

с HttpPut и HttpPost я вызываю метод setEntity и передаю свой JSON. Для HttpDelete такого метода не существует.

Если нет способа установить тело для объекта HttpDelete, может пожалуйста, свяжите меня с ресурсом, который использует супер класс HttpDelete, чтобы я мог установить метод (удалить) и установить тело. Я знаю, что это не идеально, но на данный момент я не могу изменить веб-службу.

5 ответов


вы пытались переопределить HttpEntityEnclosingRequestBase следующим образом:

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

это создаст HttpDelete - lookalike, который имеет setEntity метод. Я думаю, что абстрактный класс делает почти все для вас, так что может быть все, что нужно.

FWIW, код основан на этот источник HttpPost, что Google оказался.


следуя совету Уолтера Маднта, вы можете использовать этот код. Он работает, просто сделал это во время тестирования моего веб-сервиса REST.

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

для доступа к ответу вы можете просто сделать:response.getStatusLine();


существует различная интерпретация в вопросе, разрешено ли тело или нет в HTTP DELETE запрос. См.этой например. В спецификация HTTP 1.1 он явно не prohibied. По-моему, ты не следует использовать body на HTTP DELETE.

тем не менее я думаю, что вы должны использовать URL, как mysite/myobject/objectId (shop.com/order/1234), где objectId (часть url) является дополнительной информацией. Как альтернативу вы можете использовать параметры URL: mysite/myobject?objectName=table&color=red отправить additipnal информацию на сервер в HTTP DELETE запрос. Часть, начинающаяся с"?- это urlencoded параметры разделены dy'&'.

если вы хотите отправить более полную информацию вы можете конвертировать данные в JSON в отношении DataContractJsonSerializer или JavaScriptSerializer а затем отправить преобразованные данные (строка, которую я называю ) также в качестве параметра: mysite/myobject?objectInfo=myJsonData.

Если вам нужно отправить слишком много дополнительных данных в составе HTTP DELETE запрос, так что у вас есть проблема с длиной URL, то вы, вероятно, лучше изменить дизайн вашего приложения.

обновлено: Iy вы хотите отправить некоторое тело на HTTP DELETE, вы можете сделать это, например, как следующее

// 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

полный код может быть немного сложнее, но это уже будет работать. Тем не менее Я продолжаю говорить, что веб-служба, необходимая для данных в теле HTTP-запроса на удаление, плохо спроектирована.


использовать это,

class MyDelete extends HttpPost{
    public MyDelete(String url){
        super(url);
    }
    @Override
    public String getMethod() {
        return "DELETE";
    }
}

в модернизацию

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

вы должны вызвать условие, через что-то и потенциально должны сделать некоторую фильтрацию для url/заголовка/тела, чтобы удалить триггер,

если Удалить url / body / header достаточно уникален, чтобы не сталкиваться с post или get-запросами.