【问题标题】:How to send Stream<String> as response to client from REST API?如何从 REST API 发送 Stream<String> 作为对客户端的响应?
【发布时间】:2022-01-19 11:45:33
【问题描述】:

我对服务器进行了一次安静的调用,我想从该服务器将字符串作为流返回(流式传输数据)。在当前的代码实现中,我将数据存储为 List 并将包含该列表的 ResponseEntity 作为响应发送。但是 List 包含大量数据,我们要实现内存优化。因此,作为一种解决方案,我们希望从其余 api 逐块流式传输 List ,并在客户端对数据进行处理。我不想将数据直接写入 StreamingResponseBody 允许的 OutputStream。

当前 API:

@RestController
@RequestMapping(value = "/rest/api/")
public class StringRestController {

    @RequestMapping(value = "/stream", method = RequestMethod.GET)
    public ResponseEntity<List<String>> getMessage(HttpServletRequest request, HttpServletResponse response) {
        
        List<String> mList = new ArrayList<>();
        
        List<Long> dataList = getListFromDb();

        //Here do something with dataList and store List<String> in mList

        if (CollectionUtils.isEmpty(mList)) {
            return ResponseEntity.notFound().build();
        } else {
            return new ResponseEntity<>(mList, HttpStatus.OK);
        }

    }
}

我希望数据被流式传输,因为 List 很大。一次全部发送存在性能问题,并且从内存优化的角度来看,它可能会导致问题。我们使用的是 Java 1.8 和 Spring 3.0。

【问题讨论】:

  • 是时候实现服务器端分页了
  • 实际上,我想将响应中的数据获取到另一个应用程序中,并且需要将整个数据处理并写入文件。这就是框架的设计方式。

标签: java spring rest java-stream


【解决方案1】:

我建议你自己实现分块。

您描述的分块仅涉及将数据传输到客户端。 您已经提到“从内存优化的角度来看它可能会导致问题”。这里的大问题是你从数据库中加载整个列表。这也需要分块。

因此实现默认情况下仅从数据库加载一定数量的元素(如 100 个)。在响应中告诉客户“这里有 100 个,但还有更多”。然后客户端需要发送额外的请求,其中包含“我已经有 100 个,再给我 100 个”的信息。

如您所见,这不是通过简单的注释或其他东西可以完成的,它需要您更改您的 api 字段。

【讨论】:

  • 我明白了。我将如何返回分块数据作为响应?
  • 使用 getListFromDb(from, to) 之类的东西,fromto 来自客户端的请求作为参数。您可以添加一些验证 to-from &gt; 100 太大或什么的。
猜你喜欢
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 2019-11-23
  • 2015-01-28
  • 2016-08-17
  • 1970-01-01
相关资源
最近更新 更多