我正在使用一个 Rest API,它从 SQL Server 数据库中公开了 6212514 行。 REST API 的响应是 JSON,代表数据库行。
为了调用此 API REST 并获取孔数据,我在每次迭代中通过参数 offset 和 limit 使用分页: 示例:
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=1&buCd=XXX
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=2&buCd=XXX
。 。 .
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=760&buCd=XXX
limit是每次调用REST API返回的对象数量,offset是页码
示例:limit = 8000 and offset 1:调用将返回第1页的前8000个json对象
要获取 6212514 行,我需要执行 776 次分页/调用客户端 API REST (= 6212514 /8000) 来获取我需要存储在数据库 SQL Server 表中或使用这 6212514 行创建 csv 文件的所有结果。
实际上,我在 Spring Boot 应用程序(版本 2.5.1)(独立 Spring Boot 而非 REST API)(Java 11 / Spring webflux / Webclient)中使用此代码来使用客户端 REST API 并通过分页获取所有数据:
在服务JAVA类中:
My Spring Webclient 使用 REST API :
public DwCopaServiceImpl() {
this.webClient = WebClient.builder()
.codecs(codecs ->codecs.defaultCodecs().maxInMemorySize(memSize) )
.baseUrl(API_BASE_URL)
.defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
.build();
}
我正在使用 Reactive Mono 来非阻塞调用 API 并迭代所有分页 util the response.isLast() 为 false(此字段表示此 REST API 页面是最后一页)
DwCopaEntity 是一个实体,它呈现一行( JSON )并包含许多字符串字段 :
public Mono<List<DwCopaEntity>> getItems() {
String url = "/dwcopa/getSlice?limit="+limit+"&offset="+offset+"&buCd="+BUCD;
return fetchItems(url).expand(response -> {
if (**response.isLast()** ) {
return Mono.empty();
}
offset += 1 ;
return fetchItems("/dwcopa/getSlice?limit="+limit+"&offset="+offset+"&buCd="+BUCD);
}).flatMap(response -> Flux.fromIterable(response.getContent())).collectList();
}
private Mono<ResponseApiNeo> fetchItems(String url) {
System.out.println(url);
return webClient.get().uri(url).retrieve().bodyToMono(ResponseApiNeo.class);
}
之后获得所有结果:
writeStreamToFile ( myService.getItems().block().parallelStream().map(data -> data.toString()), "C:\\Users\\myfolder\\Documents\\optfile.txt") ;
我是 webflux 和 Webclient 的新手。此解决方案需要 25 分钟才能获取所有 Api REST 页面并创建一个未经客户端验证的文件 txt:
有没有更好的多线程解决方案:
非常感谢您的帮助。
您的 API 是否返回计数(单独或通过分页响应的属性)?
如果是这样(并且您的数据以一致的顺序返回),您可以将总数除以页面大小并生成并发请求块(同时执行 100% 的请求可能会过度加载您的服务和数据库,并导致花费更长时间而不是按顺序执行所有请求)。
然后,您需要将所有响应重新组合到正确的位置。
我假设您无法控制您正在使用的 API,否则我建议将其转换为流端点(但是您会遇到长时间运行操作、中断后恢复等问题)