How to make multiple API calls in sequential order - java

I need to call two APIs A1 and A2 but not parallelly. A2 would get called only if A1 returns some flag value in its JSON response.
I'm aware of how to make an http call in java using Httpclient. one way is to write one code to make first call and parse its response and again use the same code to make another call.Is their any other smart way which automate this process for us where I will pass both the request and the condition on which second one need to call like it is possible in Rxjava
Follwing is the Rxjava code snippet (Reference : (RxJava Combine Sequence Of Requests))
api1.items(queryParam)
.flatMap(itemList -> Observable.fromIterable(itemList)))
.flatMap(item -> api2.extendedInfo(item.id()))
.subscribe(...)
How can I accomplish this in Java? Is there any Java feature that already exists and will allow me to make a multiple sequential call?
I tried searching for existing solutions but they were not in Java.

You can use HttpURLConnection to do an API call.
Check response and accordingly trigger another call.
Something like this
public static void main(String[] args) throws IOException {
String response1 = sendGET("http://url1");
if(response1 != null && response1.contains("true")){
String response2 = sendGET("http://url2");
}
}
private static String sendGET(String url) throws IOException {
URL obj = new URL(url);
StringBuffer response = new StringBuffer();
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
} else {
System.out.println("GET request not worked");
}
return response.toString();
}

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

How to get correct data from HTTP Request

I'm trying to get my user information from stackoverflow api using a simple HTTP request with GET method in Java.
This code I had used before to get another HTTP data using GET method without problems:
URL obj;
StringBuffer response = new StringBuffer();
String url = "http://api.stackexchange.com/2.2/users?inname=HCarrasko&site=stackoverflow";
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But in this case I'm getting just stranger symbols when I print the response var, like this:
�mRM��0�+�N!���FZq�\�pD�z�:V���JX���M��̛yO^���뾽�g�5J&� �9�YW�%c`do���Y'��nKC38<A�&It�3��6a�,�,]���`/{�D����>6�Ɠ��{��7tF ��E��/����K���#_&�yI�a�v��uw}/�g�5����TkBTķ���U݊c���Q�y$���$�=ۈ��ñ���8f�<*�Amw�W�ـŻ��X$�>'*QN�?�<v�ݠ FH*��Ҏ5����ؔA�z��R��vK���"���#�1��ƭ5��0��R���z�ϗ/�������^?r��&�f��-�OO7���������Gy�B���Rxu�#:0�xͺ}�\�����
thanks in advance.
The content is likely GZIP encoded/compressed. The following is a general snippet that I use in all of my Java-based client applications that utilize HTTP, which is intended to deal with this exact problem:
// Read in the response
// Set up an initial input stream:
InputStream inputStream = fetchAddr.getInputStream(); // fetchAddr is the HttpURLConnection
// Check if inputStream is GZipped
if("gzip".equalsIgnoreCase(fetchAddr.getContentEncoding())){
// Format is GZIP
// Replace inputSteam with a GZIP wrapped stream
inputStream = new GZIPInputStream(inputStream);
}else if("deflate".equalsIgnoreCase(fetchAddr.getContentEncoding())){
inputStream = new InflaterInputStream(inputStream, new Inflater(true));
} // Else, we assume it to just be plain text
BufferedReader sr = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
StringBuilder response = new StringBuilder();
// ... and from here forward just read the response...
This relies on the following imports: java.util.zip.GZIPInputStream; java.util.zip.Inflater; and java.util.zip.InflaterInputStream.

Java http get request slower than postman get request

I'm trying to send a get request in order to get a website content.
When I'm using Postman it takes about 70-100 ms, but when I use the following code:
String getUrl = "someUrl";
URL obj = new URL(getUrl);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", "Mozilla/5.0");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null)
{
response.append(inputLine);
}
in.close();
response.toString();
it takes about 3-4 seconds.
Any idea how to get my code work as fast as Postman?
Thanks.
Try to find a workaround for the while loop. Maybe that is your bottleneck. What are you even getting from your URL? Json object or something else?
Try http-request built on apache http api.
HttpRequest<String> httpRequest = HttpRequestBuilder.createGet(someUri, String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer())
.addDefaultHeader("User-Agent", "Mozilla/5.0")
.build();
public void send(){
String response = httpRequest.execute().get();
}
I higly recomend read documentation before use.

Repeated invocations of Twitter Search API getting stalled after a couple of times

I am using Twitter Search API to get count of tweets on a given search string. Since API returns only number of tweets specified by 'count' parameter in the URL, I have to send REST call to the URL multiple times.
I parse the JSON response returned after first call and get the ID of the last tweet and send that as 'max_id' in the URL next time to get more tweets.
Here is the code:
private static void sendSearchRequest(String token, String maxId) throws Exception {
System.out.println("Entering sendSearchRequest");
byte[] temp = Base64.encodeBase64(token.getBytes());
String url = "https://api.twitter.com/1.1/search/tweets.json?q=%23SearchString&count=100&include_entities=false";
//Will be null in first invocation, not null in subsequent calls
if(maxId != null)
url += "&max_id="+maxId;
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestProperty("Authorization", "Bearer " + token);
System.out.println("\nSending 'GET' request to URL : " + url);
// optional default is GET
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
con.disconnect();
//Resend the request till response is not blank.
if(response.toString().length() > 0){
maxId = parseResponse(response.toString());
System.out.println(positiveCount);
sendSearchRequest(token, maxId);
}else{
System.out.println("No more results");
return;
}
System.out.println("Exiting parseResponse");
}
private static String parseResponse(String response) {
System.out.println("Entering parseResponse");
String lastId = "";
JSONParser parser=new JSONParser();
try{
Object object = parser.parse(response);
JSONObject array = (JSONObject)object;
JSONArray jsonArray = (JSONArray)array.get("statuses");
int size = jsonArray.size();
positiveCount += size;
System.out.println(size);
//Find the index of last object in the array returned by API
JSONObject lastObject = (JSONObject)jsonArray.get(size-1);
//Get Tweet ID to be set as Max_id in next call to Twitter.
Long id = (Long)lastObject.get("id");
System.out.println(id);
lastId = id+"";
}catch(Exception e){
e.printStackTrace();
}
System.out.println("Exiting parseResponse");
return lastId;
}
The problem I am facing is that this code makes calls only couple of times. After that the call is not sent and program just hangs. I suspected it could be due to stale open connection, so I closed that manually but even that is not working.
Can anyone please tell me what is wrong here?
Thanks
Abhishek
Got the issue. It is some kind of bug/restriction in Twitter API. https://dev.twitter.com/discussions/34598 I made slight change to above code and put in a Thread.sleep(20000) before sending calls to Twitter API and it works fine. Terribly slow though :(

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