Java - HttpURLConnection PUT request with empty body - java

I'm trying make a request with Java, when I call it using cURL like this, it works:
curl -X PUT http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action -H 'Content-Type: application/json' -H 'Token: cba5f12c-af55-480f-970e-525e446ef153' -H 'Content-Length : 0'
If I call the same request without passing header Content-Length param, I get 411 HTTP error, length required.
This is my code in Java:
URL url = new URL("http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.addRequestProperty("Content-Type", "application/json");
con.addRequestProperty("Token", "cba5f12c-af55-480f-970e-525e446ef153");
con.connect();
This request is getting a 411 HTTP code response. So, I tryed to add:
con.addRequestProperty("Content-Length", "0");
But it doesn't work, so I changed to:
URL url = new URL("http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.addRequestProperty("Content-Type", "application/json");
con.addRequestProperty("Token", "cba5f12c-af55-480f-970e-525e446ef153");
con.setDoOutput(true);
con.getOutputStream().close();
con.setFixedLengthStreamingMode(0);
con.connect();
But now I'm getting 400 HTTP code.
How can I do a PUT request with an empty body and setting content length to match the cURL call?

using the HttpUrlConnection, you should use the setRequestProperty method to add headers to your request. I can see your using the "addRequestProperty" which is probably why its not working. But refer to this link for more info https://juffalow.com/java/how-to-send-http-get-post-request-in-java and heres some code that i use to for a put request
URL url = new URL(BASE_URL+"/"+userID+".json");
urlRequest = (HttpURLConnection) url.openConnection();
urlRequest.setDoOutput(true);
urlRequest.setRequestMethod("PUT");
urlRequest.setRequestProperty("Content-Type", "application/json;
charset=UTF-8");
OutputStream os = urlRequest.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
osw.write("{\"idToken\":\""+"token"+"\"}");
osw.flush();
osw.close();
urlRequest.connect();
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream)
urlRequest.getContent()));//Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject();//Maybe an array or object
well thats just sample what i use... and i hope this works for you. Happy coding.

Related

Pass json object by navigator instead of java

I have a java application with this code :
URL url = new URL("http://myurl/");
HttURLConnection connection = (HttURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutplut(true);
connection.setRequestProperty("Content-Type", "application/json");
BufferedWriter buffer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
buffer.write("{\"foo:\"0}");
buffer.flush();
I just want to do the samething in my navigatour URL bar.
Edit
I found a tool to modifier headers. Here a screenshoot of the dev tool when I load my page.
Now where did I put my Json object?
If you need to send JSON data to your URL your code should be like this,
URL url = new URL("http://myurl/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
String input = "{\"foo\":\"bar\"}";
OutputStream ous = con.getOutputStream();
ous.write(input.getBytes());
ous.flush();
if (con.getResponseCode() != HttpURLConnection.HTTP_OK)
{
throw new RuntimeException("Failed : HTTP error code : " + con.getResponseCode());
}else
{
BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null)
{
System.out.println(output);
}
}
con.disconnect();
If you need GET Method then you can place this,
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
If you need to send Request Body with the URL you can use CURL. And also you can use POSTMAN. By using this you can send requests and receive the response.
CURL will be like this,
curl -v -H "Content-Type: application/json" -X POST \
-d '{\"foo\":\"bar\"}' http://myurl/
You can use Firefox to perform what you need, Read the 2nd answer.

Java doesn't send HTTP POST Request

I'm implementing some simple java class in order to send an HTTP Request with POST method and also another java class in order to receive it.
The server works fine when I make a POST request by means of my browser(Chrome), or an application(I have used Postman in this case) but it ends up with problem when I send HTTP Request with java!
My sending HTTP class is "Sender.java", containing the following snippet:
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
//con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
//con.setRequestProperty("Content-Type","text/plain");
// Send post request
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write("Just Some Text".getBytes("UTF-8"));
os.flush();
os.close();
//connect to the Server(resides at Server.java)
con.connect();
I have commented some lines of code setting Headers like "Accept-Language" and "Content-Type" because I don't know whether or not are these headers required for the java program to work out?
The server is another java program named "Server.java". Here is the snippet related to reading HTTP Request made by the Sender.java(if need be).
int servPort = 8082;
// Create a server socket to accept HTTP client connection requests
HttpServer server = HttpServer.create(new InetSocketAddress(servPort), 0);
System.out.println("server started at " + servPort);
server.createContext("/", new PostHandler());//PostHandler implements HttpHandler
server.setExecutor(null);
server.start();
All I want is to send a plaintext as the body of my HTTP Request with the Post method. I have read plenty of sites and even related questions at this site. But it still doesn't work out. In other words, whenever I create an HTTP Request from "Sender.java", nothing appears at "Server.java". I just want to know what's wrong with my snippets and how should I fix that?
I tested this and it's working:
//Sender.java
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write("Just Some Text".getBytes("UTF-8"));
os.flush();
int httpResult = con.getResponseCode();
con.disconnect();
As you can see, connect is not necessary. The key line is
int httpResult = con.getResponseCode();
When you send a POST form using the browser, it sends the form in a certain format, defined in RFC1866, you have to recreate this on Java when making a post request.
With this format, its important you set the Content-Type header to application/x-www-form-urlencoded, and pass the body as you would do in a url with a get request.
Borrowing some code of my previous answer to POST in Java:
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
Map<String,String> form = new HashMap<>();
// Define the fields
form.put("username", "root");
form.put("password", "sjh76HSn!"); // This is a fake password obviously
// Build the body
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "="
+ URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;
// Prepare our `con` object
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try (OutputStream os = con.getOutputStream()) {
os.write(out);
}
Maybe “localhost” in the sender url does not resolve to the same ip that the server binds to? Try changing to 127.0.0.1 or your actual IP address.
try with PrintStream
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
//con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
//con.setRequestProperty("Content-Type","text/plain");
// Send post request
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
java.io.PrintStream printStream = new java.io.PrintStream(os);
printStream.println("Just Some Text");
con.getInputStream();//Send request
os.flush();
os.close();

POST request working fine with POSTMAN/Advance rest client while giving 400 error with HttpUrlConnection

I am a newbie to HttpClient so not sure what's wrong I am doing. I am hitting one POST request through HttpUrlConnection. After sending the request when I check the logs it doesn't hit the entire request. My URL is https://www.example.com/product/pd/v1/gql when I check on the server, for URI, it shows v1/gql and give 400 error. while the same request works perfectly from Postman and advance rest client.
URL obj = new URL("https://www.example.com/product/pd/v1/gql/");
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Cookie", "_bb_vid=djfhhf");
JSONObject val = new JSONObject(gqlValue2);
JSONObject jObj = new JSONObject();
jObj.put(gqlKey1, gqlValue1);
jObj.put(gqlKey2, val);
System.out.println(jObj);
OutputStreamWriter wr = new
OutputStreamWriter(conn.getOutputStream());
wr.write(jObj.toString());
wr.flush();

JSON POST Data via HttpURLConnection

I am trying to make a request to my RESTful API using Android and HttpURLConnection. The data must be sent in the JSON format via POST data.
Here is my code:
JSONObject check_request = new JSONObject();
check_request.put("username", username);
JSONObject request = BuildRequest(check_request, "username_check", false);
Log.i("DEBUG", request.toString());
// DEBUG OUTPUT: {"timestamp":1526900318,"request":{"username":"blubberfucken","type":"username_check"}}
URL request_url = new URL(apiURL);
HttpURLConnection connection = (HttpURLConnection)request_url.openConnection();
connection.setRequestProperty("User-Agent", "TheGameApp");
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "application/json; charset=UTF-8");
connection.setDoOutput(true);
connection.setDoInput(true);
OutputStream os = connection.getOutputStream();
os.write(request.toString().getBytes("UTF-8"));
os.flush();
InputStream in = new BufferedInputStream(connection.getInputStream());
String result = "";
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF8"));
String str;
while ((str = br.readLine()) != null)
{
result += str;
}
Log.i("DEBUG", result);
//JSONObject result_json = new JSONObject(result);
os.close();
in.close();
connection.disconnect();
You can see the Debug output as a Comment. The Problem is that the API does not receive any POST data. I have used PHPs var_dump to dump $_POST and $_REQUEST which both are empty arrays.
What am I missing here?
As the question popped up if the API work. This cURL command works fine with the correct result (it is the same JSON data as the debugger printed):
curl -d '{"timestamp":1526900318,"request":{"username":"blubberfucken","type":"username_check"}}' -H "Content-Type: application/json" -X POST http://localhost/v1/api.php
Just for the sake of completeness: The example above is working. The solution to the problem was pa part in PHP on the server side, where I checked the content type and used strpos to search for application/json in $_SERVER['CONTENT-TYPE'] and switched the needle and haystack (thus searching for application/json; charset=UTF8 in the string application/json instead of the other way around).

HttpURLConnection sends a POST request even though httpCon.setRequestMethod("GET"); is set

Here is my code:
String addr = "http://172.26.41.18:8080/domain/list";
URL url = new URL(addr);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setAllowUserInteraction(false);
httpCon.setRequestMethod("GET");
httpCon.addRequestProperty("Authorization", "Basic YWRtaW4fYFgjkl5463");
httpCon.connect();
OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream());
System.out.println(httpCon.getResponseCode());
System.out.println(httpCon.getResponseMessage());
out.close();
What I see in response:
500 Server error
I open my httpCon var, and what I see:
POST /rest/platform/domain/list HTTP/1.1
Why is it set to POST even though I have used httpCon.setRequestMethod("GET"); to set it to GET?
The httpCon.setDoOutput(true); implicitly set the request method to POST because that's the default method whenever you want to send a request body.
If you want to use GET, remove that line and remove the OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream()); line. You don't need to send a request body for GET requests.
The following should do for a simple GET request:
String addr = "http://172.26.41.18:8080/domain/list";
URL url = new URL(addr);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setUseCaches(false);
httpCon.setAllowUserInteraction(false);
httpCon.addRequestProperty("Authorization", "Basic YWRtaW4fYFgjkl5463");
System.out.println(httpCon.getResponseCode());
System.out.println(httpCon.getResponseMessage());
See also:
Using java.net.URLConnection to fire and handle HTTP requests
Unrelated to the concrete problem, the password part of your Authorization header value doesn't seem to be properly Base64-encoded. Perhaps it's scrambled because it was examplary, but even if it wasn't I'd fix your Base64 encoding approach.

Categories