I have to make a HTTP POST request by passing header and body. In the body, I need to provide a pageNumber
before posting data so I am starting with "1" initially. After that I will post data and I will get a JSON response back as shown below.
{
"response": {
"pageNumber": 1,
"entries": 200,
"numberOfPages": 3
},
"list": [
{
// some stuff here
}
],
"total": 1000
}
Now depending on response for pageNumber 1
, I will decide how many more calls I need to make. Now in the above response numberOfPages
are 3 so I need to make a total of three calls to the same URL. Since we already made 1 call I will make 2 more calls with pageNumber
"2" and "3" in the body.
Below is my working code. I just need to call the same URL until numberOfPages
times by just changing the body. For each call, it should be made with the corresponding pageNumber
so if numberOfPages
are 3 then I will make total 3 calls. And I am populating two maps after collecting data from each pages.
public class AppParser {
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final String lastParentIdJsonPath = "......";
private final Map<String, String> processToTaskIdHolder = new HashMap<>();
private final Multimap<String, Category> itemsByCategory = LinkedListMultimap.create();
private final int entries;
private final String siteId;
public AppParser(int entries, String id) {
this.entries = entries;
this.id = id;
collect();
}
// this is only called from above constructor
private void collect() {
String endpoint = "url_endpoint";
int number = 1;
int expectedNumber;
do {
HttpEntity<String> requestEntity = new HttpEntity<String>(getBody(number), getHeader());
ResponseEntity<String> responseEntity =
HttpClient.getInstance().getClient()
.exchange(URI.create(endpoint), HttpMethod.POST, requestEntity, String.class);
String jsonInput = responseEntity.getBody();
Stuff response = objectMapper.readValue(jsonInput, Stuff.class);
expectedNumber = (int) response.getPaginationResponse().getNumberOfPages();
if (expectedNumber <= 0) {
break;
}
List<Postings> postings = response.getPostings();
for (Postings posting : postings) {
if (posting.getClientIds().isEmpty()) {
continue;
}
List<String> lastParent = JsonPath.read(jsonInput, lastParentIdJsonPath);
String clientId = posting.getClientIds().get(0).getId();
Category category = getCategory(posting);
// populate two maps now
itemsByCategory.put(clientId, category);
processToTaskIdHolder.put(clientId, lastParent.get(0));
}
number++;
} while (number <= expectedNumber);
}
private String getBody(final int number) {
Input input = new Input(entries, number, 0);
Body body = new Body("Stuff", input);
return gson.toJson(body);
}
// getters for those two above maps
}
Now my above code is collecting data sequentially for each pages one by one so if I have high numberOfPages
then it will take some time to collect all the data for all those page numbers. Let's say if numberOfPages
is 500 then my code will be running sequentially one by one for each pageNumber. Is there any way to parallelize my above code so that we can collect data for say 5 pages at a same time? Is this possible to do? And I guess then I need to make sure my code is thread safe.
Note: HttpClient
is thread safe singleton class.