curl command line vs HttpURLConnection API service call response time differences - java

I am consuming a web services using HttpURLConnection which took 60 seconds to return the response but when I use CURL(command line) for same operation with same parameters then it took only 20 - 25 seconds to return the response.
what could be the issue in API service call through HttpURLConnection because it's taking longer time to return the response.
HttpURLConnection API call code :
`
url = new URL(this._serviceURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("Accept", "application/xml;");
connection.setRequestProperty("SOAPAction", "http://www.xxtest.com/Request");
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(xmlRequest);
wr.flush();
wr.close();
// Get Response
responseCode = connection.getResponseCode();
String xmlResponse = "";
if (responseCode == HttpURLConnection.HTTP_OK) { // success
is = connection.getInputStream();
xmlResponse = IOUtils.toString(is);
// Decode base64 and Decompress
final GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(Base64.decodeBase64(xmlResponse.getBytes())));
xmlResponse = IOUtils.toString(gzipInputStream);
}`
CURL command :
curl -XPOST -H "Content-type: text/xml" -H "SOAPAction: http://www.xxtest.com/Request" -H "Accept: application/xml;" -d #request_soap.xml 'http://www.xxtest.com/xmlservices.asmx' > response.xml
Update :
Above mentioned HttpURLConnection API call java code - when executed from a Web Application (Tomcat) then it's taking longer time(60 seconds) to return the response but when I run the same java code as standalone java program on same server then it is returning response in 20 seconds. Exactly same code. Now, I don't understand why the same code is taking longer time when it is getting executed from a Web Application.

The performance problem might be at this point
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(xmlRequest);
wr.close();
I would guess following will get better Performance.
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(xmlRequest);
out.close();

I have added Proxy.NO_PROXY in openConnection method in a HttpURLConnection API call code(mentioned in my question) and delayed response issue solved. The services which I was consuming were having proxy setting and because of that I was facing delayed response issue.
Please check below mentioned code snippet.
connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);

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 - HttpURLConnection PUT request with empty body

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.

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).

Does Java GAE UrlFetch support HTTP PUT?

How do I do an HTTP PUT request using the UrlFetch service for Google App Engine's Java runtime?
The following code in my application will send a POST request:
URL url = ...;
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(MAX_TIMEOUT); // Maximum allowable timeout on GAE of 60 seconds
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
OutputStreamWriter writer = null;
try {
writer = new OutputStreamWriter(conn.getOutputStream(), Charset.forName("utf-8"));
writer.write(jsonContent);
} finally {
if (writer != null)
writer.close();
}
}
InputStream inStream = null;
E response = null; // Unmarshalled using Jackson
try {
inStream = conn.getInputStream();
if (status != 204) { // NO CONTENT => No need to use Jackson to deserialize!
response = mapper.readValue(inStream, typeRef);
}
} finally {
if (inStream != null) {
inStream.close();
}
}
I try doing the same as POST for PUT, but I keep on getting a 405 HTTP error for Method Not Allowed. Thanks for the help.
Reference: https://developers.google.com/appengine/docs/java/urlfetch/overview
Unfortunately, GAE Java doesn't have as good of documentation as Python's version of GAE URL fetch(https://developers.google.com/appengine/docs/python/urlfetch/overview). Anyone from Google wanna say why?
I think your code works. The HTTP 405 you are seeing is coming from the server you're contacting (not all services support PUT). You can try using curl to hit the URL if you'd like confirmation that it's not your code at fault:
curl -X PUT -d "foo=bar" http://your_site.com/path/to/your/resource

Android HttpUrlConnection Response wait time

I have below code. I am getting HTTP response code -1. Just to troubleshoot, I would like to know if I should wait after making connection for a while before checking the http response code.
String requestURL = "https://www.google.com";
HttpURLConnection connection = new HttpURLConnection;
connection = (HttpURLConnection) requestUrl.openConnection();
connection.setConnectTimeout(20000);
connection.setReadTimeout(20000);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.connect();
OutputStreamWriter writer = new OutputStreamWriter(this.connection.getOutputStream());
writer.write(getHttpData());
writer.flush();
writer.close();
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new inputStreamReader(connection.getInputStream()));
}
Is getResponseCode() or getInputStream() blocking call ? Am I reading response too soon ? Should I wait ?
Thanks for the help.
One reason you could be getting the weird HTTP response code of -1 is the connection-pooling with-http-keep-alives bug that's in Android platform versions up to (and including) Froyo, ie Android v2.2.
The Android Developer Blog gives the following code snippet to resolve the problem (note that they say it doesn't include Froyo, although we found that it did - the snippet below is modified accordingly):
private void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (Integer.parseInt(Build.VERSION.SDK) <= Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
Try calling that when your app starts-up and see if it fixes your problem.

Categories