Подтвердить что ты не робот

HttpDelete с телом

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

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

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

4b9b3361

Ответ 1

Вы пробовали переопределить 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 появился.

Ответ 2

Следуя совету Walter Mudnt, вы можете использовать этот код. Он работает, просто сделал это во время тестирования моего веб-сервиса 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();

Ответ 3

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

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

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

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

ОБНОВЛЕНО. Если вы хотите отправить какой-то элемент по 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 DELETE, плохо спроектирована.

Ответ 4

используйте это,

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

Ответ 5

в модификации

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/header/body, чтобы удалить триггер,

если заголовок delete url/body/не будет уникальным, чтобы не столкнуться с сообщением или получить запросы.