ResponseEntity<Stream<MyObject>>是否会将所有内容存储在内存中?

5

这似乎是一个简单的问题,但我找不到答案。

在Spring Boot中,我有一个控制器方法,返回json:

@GetMapping
public ResponseEntity<Stream<MyObject>> get() {
  return ResponseEntity
    .ok()
    .contentType(MEDIA_JSON)
    .body(service.stream());
}


这是否已经逐块流式传输给用户,还是在返回给用户之前将整个流加载到内存中?
1个回答

7
我没有在文档中找到任何信息,但可以尝试并查看其行为。
让我们创建2个端点和一个无限的对象流:
@RestController
public class MyController {

    @GetMapping("/stream")
    public ResponseEntity<Stream<MyObject>> stream() {
        return ResponseEntity.ok(getStream());
    }

    @GetMapping("/nostream")
    public ResponseEntity<List<MyObject>> noStream() {
        return ResponseEntity.ok(getStream().collect(Collectors.toList()));
    }

    private Stream<MyObject> getStream() {
        return IntStream.iterate(0, i -> i + 1)
                .mapToObj(i -> new MyObject());
    }

    static class MyObject {

        private String name = "foo";

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

访问 http://localhost:8080/stream 将立即响应,生成一个无限序列的 [{"name":"foo"},{"name":"foo"}...

如果你对应用程序进行分析,你会发现它可以在几分钟内继续执行而不增加内存使用量:

Profiling with stream

相反,调用 http://localhost:8080/nostream 端点将很快导致 java.lang.OutOfMemoryError

Profiling without stream


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接