当前位置: 首页 > 知识库问答 >
问题:

从REST API(JSON响应)中收集一系列分页结果(776页),并将最终结果插入到DB SQL或创建csv文件

游炳
2023-03-14

我正在使用一个Rest API,它从SQL Server数据库中公开了6212514行。REST API的响应是表示数据库行的JSON。

为了调用这个API REST并获取hole数据,我在每次迭代中都通过参数offset和limit使用分页:

    null

http://localhost:8080/myapi/dwcopa/getslice?**limit**=8000&**offset**=1&bucd=xxx

  • 呼叫2:

http://localhost:8080/myapi/dwcopa/getslice?**limit**=8000&**offset**=2&bucd=xxx

...

  • 呼叫760:

http://localhost:8080/myapi/dwcopa/getslice?**limit**=8000&**offset**=760&bucd=xxx

在服务JAVA类中:

使用REST API的Spring Webclient:

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 response.islast()为false(此字段指示REST API的此页是最后一页)

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:

有没有更好的解决方案多线程:

  • 分页a hole rest API rest(760页):(大数据响应:JSON总共6 GB)
  • 将所有响应插入SQL数据库或创建csv文件?
  • 性能至关重要(获取所有数据最多5分钟)
  • 是否应该更正代码以获得更快的速度/添加线程?

非常感谢你的帮助。

共有1个答案

司寇光华
2023-03-14

您的API是否返回一个计数(无论是自己返回还是通过分页响应的属性返回)?

如果是这样(并且您的数据是以一致的顺序返回的),您可以将总数除以页面大小,并生成大量并发请求(并发执行100%的请求可能会过度加载您的服务和db,并导致它比顺序执行所有请求花费更长的时间)。

然后,您需要将所有响应重新组合到正确的位置。

我假设您无法控制正在使用的API,否则我建议将其转换为流endpoint(但这样您就会遇到长时间运行操作、中断后恢复等问题)

 类似资料:
  • 我正在从数据库中读取pdf文件列表,对它们进行解析,并用它们执行一些任务 当我阅读这个pdf列表时,我发现从pdf中提取图像需要花费更多的时间,而且我不需要阻止我的主线程来阅读图像。所以我想在一个单独的线程中执行提取图像 我想从一个又一个pdf中读取图像,而不是一次将所有pdf加载到内存中(由于内存问题)。所以我只想要两条线;一个应该是主线程(从pdf中读取一些文本并执行其他操作),另一个应该是提

  • JDBC ResultSet是否支持分页?或者我应该通过缓存结果集来在我的服务中实现内部分页。我寻找这样一个解决方案的原因是-我不允许更改表结构。如果允许,我可以有一个自动增量列,然后使用该列和限制上的子句获取数据。

  • 我正在使用基于Laravel和Twig的OctoberCMS。 十月有一个范围分页功能,但它缺乏我需要的功能,所以我必须使用Laravel返回结果和分页。 我有一个厨房分类和图像数据库记录。 我试图从URL中获取标识符,以过滤回数据库结果。 问题 代码返回自然图像并显示分页。但是当我点击一个页码时,url会变成或,但页面按钮停留在上,记录/图像不会更改。 这就像php在下一页重置,并再次显示第1页

  • 定义 结果页 图片展示 代码演示 import Result from 'pile/dist/components/result' <Result size="big" title="成功" message="用于表示操作成功" iconHtml={<span className="icon-toast_right"></span>} /> 属性 参数 描述 数据类型 默认值 size 三种展

  • 结果页通常来说可以认为进行一系列操作步骤后,作为流程结束的总结性页面。结果页的作用主要是告知用户操作处理结果以及必要的相关细节(可用于确认之前的操作是否有误)等信息;若该流程用于开启或关闭某些重要功能,可在结果页增加与该功能相关的描述性内容。 实现这个功能比较容易,使用微信 API wx.navigateTo()即可,mpvue框架中示例代码如下: <template> <div class=

  • 问题内容: 想象一下,我有两种记录:一个存储桶和一个项目,其中存储在存储桶中的项目,而存储桶中的项目可能相对较少(通常不超过4个,从不超过10个)。这些记录被压缩为一个(具有更多存储桶信息的项目),并放置在Elasticsearch中。我要解决的任务是通过依赖项属性的过滤查询一次找到500个存储桶(最大),其中包含所有相关项,而我受困于限制/抵消聚合。我该如何执行此类任务?我看到聚合使我可以控制相