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?
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.
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.
DELETE can have a body`. Body is allowed but should not be relevant to the request.
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.
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 ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With