Java - Multithread - HTTP GET- Why getting faster with more open connections? - java

I want to test my application if it can handle many Request parallel. To test this i simply initialised the Request about 50 times. Each Request in a own Thread.
The run() Method looks sth. like this with a bit more Stuff.
public void run(){
URL getUrl = new URL(url);
HttpURLConnection con = (HttpURLConnection) getUrl.openConnection();
con.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
while ((data = br.readLine()) != null) {
sb.append(data);
}
br.close();
}
The stragne thing is that with more Request the time per Request is reducing significant to about 50%. Why is this happening? Does the Java HTTP Connection cache the Request?

Related

How do I make async http get requests in Java?

I wrote a program where I call many http get request. It takes like half a minute till all the get requests are done but it needs to be done within a second, this can be achieved with calling this method asynchronously, right? But how?
This is what my get request looks like:
public static String dataRequest(String link) throws IOException {
URL url = new URL(link);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP Error code : " + conn.getResponseCode());
}
InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(in);
String output;
String result = "";
while ((output = br.readLine()) != null) {
result += output;
}
conn.disconnect();
return result;
}
I tried using RxJava but I couldn't get it to work at all. I'm in a Maven JavaFx project. This method is in my getData class.
You can try using thread with ForkJoinPool
For example -> https://www.baeldung.com/java-fork-join

Send multiple GET API requests using HttpURLConnection in java

I am using below code to send GET api request. The url below has a parameter e.g. String url = "https://my/api"+variable+"test". I am using for loop to iterate through the list of variables (which are more than 2000) and create url to send get API request using below code. I want to send multiple api requests in parallel to reduce the overall time. Please suggest what is the best way for that.
URL _url = new URL(url);
HttpURLConnection con = (HttpURLConnection) _url.openConnection();
Authenticator authenticator = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication(user,
password.toCharArray()));
}
};
Authenticator.setDefault(authenticator);
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONObject Obj = new JSONObject(response.toString());
Suggest you check out the Java ExecutorService:
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
You can create async tasks and execute them on a thread pool, then wait for the results to complete. There are several good tutorials for this.
For instance:
https://www.baeldung.com/java-executor-service-tutorial

HttpURLConnection getInputStream() has one second delay

I am using HttpURLConnection for making POST requests. I observe always the same behaviour during tests:
first request runs very fast (miliseconds)
all following requests take one second + some miliseconds
So something is causing 1 second delay. What can it be? The delay is happening exactly in HttpURLConnection#getInputStream().
I replaced the implementation with HttpClient - then everything is OK, no second delays (so it is not the server fault). But I really don't want to use any external dependency, so I would like to fix the HttpURLConnection thing... Any ideas?
Below current implementation. I tried some tips from stackoverflow (adding headers to the request), but with no success.
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Length", ""
+ (body == null ? 0 : body.length));
// Send post request
con.setDoOutput(true);
OutputStream wr = con.getOutputStream();
if (body != null) {
wr.write(body);
}
wr.flush();
wr.close();
BufferedReader rd = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String line;
String result = "";
while ((line = rd.readLine()) != null) {
result += line;
}
rd.close();
con.disconnect();
return result;
PS: It is about jse, not android.
You're never closing the input stream from the connection - that may mean that the connection isn't eligible for pooling, and on the next attempt it's waiting for up to a second to see if the previous request's connection will become eligible for pooling.
At the very least, it would be a good idea to close the stream. Use a try-with-resources block if you're using Java 7 - and ditto for the writer.
As an aside, I suggest you explicitly state the encoding you expect when reading - or use a higher-level library which detects that automatically based on headers.

How to get the Response Back from the Remote Server using an HttpURLConnection Object?

I am trying to send an HTTP POST Request to a remote server using an instance of the HttpURLConnection class. Although, I am able to get a response code and a response message, when I try to write the input stream into a StringBuffer, I am not able to actually read any lines.
When I analyzed the packets sent from WireShark, I noticed that a full response was being sent from the remote server. My only guess as to why I am not able to see it in the Java program is because the time in which I try to read from the InputStream is too late.
So, how do I read the immediate, full response from the remote server using my HttpURLConnection object? Below is the code that I am using:
HttpURLConnection conn = null;
String urlStr = "...";
URL url = null;
try
{
url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
...
BufferedReader rd = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
{
sb.append(line);
}
rd.close();
...
}...
Okay, never mind. It turns out that what I was looking for was in the HTTP Respone's header. So, I got what I needed by looking through its headers. ::Face Palm::

Using an API of a website in a servlet . Is this the right way?

public java.lang.StringBuffer getRequestURL()
I am using this method to call the API of another website which gives XML data as response to it . Is this the right method to be used with HTTPrequest/response. ?
No. You should use new URL(url).openConnection(), or some abstraction like http components or a rest-client
If you want to make HTTP requests from within a Servlet you do it as you would from any process. Something like this:
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.targetdomain.com/api?key1=value1&key2=value2...");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000); // 5 seconds
conn.setRequestMethod("GET");
conn.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
StringBuffer bf = new StringBuffer();
while ((line = rd.readLine()) != null) {
bf.append(line);
}
conn.disconnect();
//... pass bf to an XML parser and do your processing...
}
Depending on whatever XML parser you're using, you can probably skip buffering the response and putting it in a StringBuffer, and instead pass your parser the response InputStream directly.

Categories

Resources