Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP Delete with Request Body issues

Can anyone explain the following:

package com.foo.bar;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import org.springframework.util.FileCopyUtils;

public class ATest {

    public static void main(String[] args) throws Exception {
       try {
           final String payload = "{\"parentExecutor\":\"foo1233\"}";
           URL url = new URL("http://localhost/notes");
           final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
           connection.setRequestMethod("DELETE");
           connection.setRequestProperty("Accept", "application/json");
           connection.setRequestProperty("Content-Type", "application/json");
           FileCopyUtils.copy(payload.getBytes(), connection.getOutputStream());
           connection.connect();
           final InputStream is = connection.getInputStream();
           int b = is.read();
           String result = "";
           while (b != -1) {
               result += (char) b;
               b = is.read();
           }
           System.out.println(connection.getResponseCode());
           System.out.println(result);
           is.close();
       }
       catch (final ProtocolException e) {
          e.printStackTrace();
       }
   }
}

The example above throws the following exception:

java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:995)
    at com.foo.bar.ATest.main(ATest.java:24)

However if I add a call to setDoOutput(true), the following exception is thrown:

java.net.ProtocolException: HTTP method DELETE doesn't support output
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1004)
    at com.foo.bar.ATest.main(ATest.java:25)

Then, if I change the protocol from http to https no exception is thrown and I get back the expected response code and content from the server. I looked at the source code and can follow the calls and trace where the exceptions are happening, but why would it be OK to make such a request via HTTPS but not HTTP?

like image 306
Jcx Jc Avatar asked Feb 01 '12 17:02

Jcx Jc


People also ask

Does HTTP delete support request body?

client:http service does not include a body in requests that use the DELETE method. It is common practice to qualify HTTP DELETE requests by including query parameters in the URL. While it is not explicitly forbidden to include a body with a DELETE request, most HTTP servers do not support it.

Can we pass request body in delete request?

Yes it is allowed to include a body on DELETE requests, but it's semantically meaningless. What this really means is that issuing a DELETE request with a request body is semantically equivalent to not including a request body.

Can a delete include a body?

DELETE can have a body`. Body is allowed but should not be relevant to the request.

Should delete return 200 or 204?

A 204 ( No Content ) status code if the action has been enacted and no further information is to be supplied. A 200 ( OK ) status code if the action has been enacted and the response message includes a representation describing the status.

Can HTTP request have body?

No, HTTP GET requests cannot have a message body. But you still can send data to the server using the URL parameters. $http GET request not sending data (request body) when ...


1 Answers

This is a limitation (I'd consider it to be a bug or at least a stupid feature) of HttpURLConnection. You're at least not the only one who encounters this when dealing with REST webservices using URLConnection.

Consider using Apache HttpComponents Client instead.

like image 97
BalusC Avatar answered Oct 15 '22 16:10

BalusC