Making PUT request with JSON data using HttpURLConnection is not working - java

I'm trying to make PUT request with JSON data using HttpURLConnection in Java. The way I do it doesn't work. I get no errors so I don't know what the problem is.
public static void main(String[] args) {
URL url;
try {
url = new URL("http://fltspc.itu.dk/widget/515318fe17450f312b00153d/");
HttpURLConnection hurl = (HttpURLConnection) url.openConnection();
hurl.setRequestMethod("PUT");
hurl.setDoOutput(true);
hurl.setRequestProperty("Content-Type", "application/json");
hurl.setRequestProperty("Accept", "application/json");
String payload = "{'pos':{'left':45,'top':45}}";
OutputStreamWriter osw = new OutputStreamWriter(hurl.getOutputStream());
osw.write(payload);
osw.flush();
osw.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And here is the request I'm actually trying to make:
I was already making GET requests to the resource within the same app and it worked fine. I would be very grateful for all tips on how can I debug that or how can I try to do it some other way. So far I tried only using OutputStream instead of OutputStreamWriter but it doesn't work neither.

The Sun (Oracle) implementation of HttpURLConnection caches the content of your post unless you tell it to be in streaming mode. The content will be sent if you start interaction with the response such as:
hurl.getResponseCode();
Also, according to RFC 4627 you can not use single quotes in your json (although some implementations seem to not care).
So, change your payload to:
String payload = "{\"pos\":{\"left\":45,\"top\":45}}";
This example works for me
public class HttpPut {
public static void main(String[] args) throws Exception {
Random random = new Random();
URL url = new URL("http://fltspc.itu.dk/widget/515318fe17450f312b00153d/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("PUT");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
osw.write(String.format("{\"pos\":{\"left\":%1$d,\"top\":%2$d}}", random.nextInt(30), random.nextInt(20)));
osw.flush();
osw.close();
System.err.println(connection.getResponseCode());
}
}

Related

Persisting the same HttpURLConnection to send multiple JSON lists separately: what should ContentLength be?

Example problem:
I have an initial list of size 1000.
I want to POST the data of this list to a URL in 10 HTTP requests, where each request writes a ("sublist") of size 100 (since 1000 / 10 = 100).
Now I want to do the above using Java's HttpURLConnection, I have this method:
private static HttpURLConnection open(String endpoint) throws IOException {
URL url = new URL(endpoint);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setDoOutput(true);
connection.setDoInput(true);
// Should I also set Content-Length? Why or why not?
connection.setRequestMethod("POST");
return connection;
}
My issue is that I don't know what the content length should be. Given the example above, should it be 1000 (the total size of the list fetched)? Or should it be 100 (the size of an individual list that will be sent throughout the session)? Note that I wish for the connection to be persistent; no need to open a new connection for every list to be sent.
For reference, my function that does the POST looks like the below:
private static int post(String endpoint, String payload) throws IOException {
int response;
try {
HttpURLConnection connection = open(endpoint, payload.length());
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(connection.getOutputStream()))) {
writer.write(payload);
}
try (InputStream is = connection.getInputStream()) {
IOUtils.consume(is);
} catch (IOException e) {
InputStream es = connection.getErrorStream();
IOUtils.consume(es);
es.close();
}
response = connection.getResponseCode();
System.out.println(String.format("Sent batch with response code %d.", response));
} catch (IOException e) {
throw new IOException(e);
}
return response;
}

Call httpconnection with encoding not working

i need to call a service get using http connection, the response contains arabic characters, but when i call it using the code below
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
InputStream in = new BufferedInputStream(conn.getInputStream());
response = IOUtils.toString(in, "UTF-8");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
the reponse is
1|U|����� ������|$2|L|���� �������|$3|S|����
I tried another solution not using Commons-io but also not working
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.connect();
int statusCode = connection.getResponseCode();
//Log.e("statusCode", "" + statusCode);
if (statusCode == 200) {
sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1) {
sb.append(tmp, 0, l);
}
//sb = buffer.toString();
}
connection.disconnect();
if (sb != null)
serverResponse = sb.toString();
Do i need to change anything from web service??? but when i call it from browser all characters show clearly with no problem
any suggestion?
Maybe the server is not using UTF-8, your code is trying to use UTF-8 to decode the data but that will only work if the server is using the same encoding.
The browser works because maybe it is using the HTTP header "Content-Encoding" which should indicate the encoding used for the data.
Please decode your string response
String dateStr = URLDecoder.decode(yourStringResponse, "utf-8");

Chromecast communication using JAVA/Android and Http

I'm trying to communicate with Chromecast using Http. I'm using this documentation about API methods and trying to execute an Youtube video on it. Following this answer to execute a post call, for now I have:
#Override
public void run() {
try {
String urlParameters = "v=oHg5SJYRHA0";
byte[] postData = urlParameters.getBytes();
int postLenght = postData.length;
//url is: new URL("http://192.168.25.99:8008/apps/YouTube")
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setInstanceFollowRedirects(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Content-Length", Integer.toString(postLenght));
urlConnection.setUseCaches(false);
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.write(postData);
wr.flush();
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This command execute properly but nothing happening in Chromecast.
What am I doing wrong?
It works, I just forgot to call the response:
String responseMessage = urlConnection.getResponseMessage();
When I call this method, the video executes.

HttpURLConnection: No data in the POST request

I have created a Django Rest server. And I am trying to POST a JSON content in java using HttpURLConnection. However, when I am registering OutputStream in java, the server get a POST request with no JSON content. Hence the server rejecting the request with HTTP response code 400. I did write JSON data just after registering OutputSream. May be POST has been made before writing to OutputStream. The following is the code in JAVA.
public static void post(HttpURLConnection urlConnection1)
throws IOException, InterruptedException {
// urlConnection.setRequestMethod("POST");
URL url = new URL("http://127.0.0.1:8000/message/");
byte[] authStr=Base64.encodeBase64("sp:password".getBytes());
String enc=new String(authStr);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic "+ enc);
try {
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
urlConnection
.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setInstanceFollowRedirects(false);
OutputStream out = urlConnection.getOutputStream();
//Thread.sleep(5000);
writeStream(out);
out.flush();
InputStream in = urlConnection.getInputStream();
readStream(in);
} finally {
urlConnection.disconnect();
}
}
private static void writeStream(OutputStream out) {
// TODO Auto-generated method stub
try {
JSONObject grp = new JSONObject();
JSONObject gp = new JSONObject();
gp.put("id", "g3bj25");
gp.put("from", "someone");
out.write(gp.toString().getBytes());
System.out.println(gp.toString());
} catch (IOException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Do I have to make any changes in server side so that it waits for content?
The problem is, that your URL is not complete, the name of the script is missing.
URL url = new URL("http://127.0.0.1:8000/message/");
supposes that you are calling http://127.0.0.1/message/index.php but here you're not allowed to let the index.php (or whatever) implicit.
The script gets called, but the POST data is not sent, or it is truncated by the Webserver when handling the request. I had the same problem and spent hours until I found the reason. Then I did not dig further to find out exactly where the POST data gets dropped.

Posting to a webservice using httpurlconnection

How come I am only allowed to make posts to .com url's but not .asmx url's? Im a bit confused as what I want to generally do is send xml content to a .asmx url web service eventually. Can anyone supply me with tips why this doesn't work, and how I can post to a .asmx file?
public class POSTSenderExample {
public String echoCuties(String query) throws IOException {
// Encode the query
String encodedQuery = URLEncoder.encode(query, "UTF-8");
// This is the data that is going to be send to itcuties.com via POST request
// 'e' parameter contains data to echo
String postData = "e=" + encodedQuery;
URL url = new URL("http://echo.itgeeeks.asmx");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", String.valueOf(postData.length()));
// Write data
OutputStream os = connection.getOutputStream();
os.write(postData.getBytes());
// Read response
StringBuilder responseSB = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ( (line = br.readLine()) != null)
responseSB.append(line);
// Close streams
br.close();
os.close();
return responseSB.toString();
}
// Run this example
public static void main(String[] args) {
try {
System.out.println(new POSTSenderExample().echoCuties("Hi there!"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Using "POST" is correct.
Instead of calling
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
you have to call
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
(if you are using utf-8 encoding which is probably the case).
You also have to set the SOAP Action in the http- Header:
connection.setRequestProperty("SOAPAction", SOAPAction);
You can find the SOAP Action eihter in the wsdl- file. What I did to find out all expected Parameters: I used a working WS Client, and traced the TCP traffic in order to find out the expected HTTP headers.

Categories