【发布时间】:2018-07-05 14:32:26
【问题描述】:
我必须通过传递标头和正文来发出 HTTP POST 请求。在正文中,我需要在发布数据之前提供pageNumber,所以我最初从“1”开始。之后我会发布数据,我会收到如下所示的 JSON 响应。
{
"response": {
"pageNumber": 1,
"entries": 200,
"numberOfPages": 3
},
"list": [
{
// some stuff here
}
],
"total": 1000
}
现在根据pageNumber 1 的回复,我将决定我还需要拨打多少电话。现在在上面的响应中numberOfPages 是 3,所以我需要对同一个 URL 进行总共三个调用。由于我们已经拨打了 1 个电话,我将再拨打 2 个电话,其中 pageNumber 正文中包含“2”和“3”。
以下是我的工作代码。我只需要通过更改正文来调用相同的 URL,直到 numberOfPages 次。对于每个呼叫,都应该使用相应的pageNumber,所以如果numberOfPages 是 3,那么我将总共拨打 3 个电话。从每个页面收集数据后,我正在填充两张地图。
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
}
现在我上面的代码正在为每一页按顺序收集数据,所以如果我有很高的numberOfPages,那么收集所有这些页码的所有数据需要一些时间。假设numberOfPages 是 500,那么我的代码将为每个 pageNumber 一个接一个地依次运行。有什么方法可以并行化我的上述代码,以便我们可以同时收集 5 页的数据?这可能吗?而且我想我需要确保我的代码是线程安全的。
注意:HttpClient 是线程安全的单例类。
【问题讨论】:
标签: java multithreading performance thread-safety guava