2

我是 Spring 5 和响应式编程的新手。我的问题是通过 REST API 为数据库创建导出功能。用户点击 GET 请求 -> 服务器读取数据并将数据作为 zip 文件返回。因为 zip 文件很大,所以我需要流式传输这些数据。我的代码如下:

    @GetMapping(
    value = "/export",
    produces = ["application/octet-stream"],
    headers = [
              "Content-Disposition: attachment; filename=\"result.zip\"",
              "Content-Type: application/zip"])
    fun streamData(): Flux<Resource> = service.export()

我使用 curl 如下:

curl http://localhost/export -H "Accept: application/octet-stream"

但它总是返回 406 Not Acceptable。有人帮忙吗?

太感谢了

4

2 回答 2

0

注释的headers属性@GetMapping不是应该写入 HTTP 响应的标头,而是映射标头。这意味着您的@GetMapping注释要求 HTTP 请求包含您列出的标头。这就是为什么请求实际上没有映射到您的控制器处理程序的原因。

现在您的处理程序返回类型看起来不正确 -Flux<Resource>意味着您打算返回0..* Resource实例并且它们应该被序列化。在这种情况下,像这样的返回类型ResponseEntity<Resource>可能是更好的选择,因为您可以在 上设置响应标头ResponseEntity并使用Resource.

于 2018-01-24T09:14:30.237 回答
-1

对吗,伙计?使用blockLast时,我仍然觉得最后一行的这个解决方案不好。

@GetMapping("/vehicle/gpsevent", produces = ["application/octet-stream"])
fun streamToZip(): ResponseEntity<FileSystemResource> {
    val zipFile = FileSystemResource("result.zip")
    val out = ZipOutputStream(FileOutputStream(zipFile.file))
    return ResponseEntity
        .ok().cacheControl(CacheControl.noCache())
        .header("Content-Type", "application/octet-stream")
        .header("Content-Disposition", "attachment; filename=result.zip")
        .body(ieService.export()
            .doOnNext { print(it.key.vehicleId) }
            .doOnNext { it -> out.putNextEntry(ZipEntry(it.key.vehicleId.toString() + ".json")) }
            .doOnNext { out.write(it.toJsonString().toByteArray(charset("UTF-8"))) }
            .doOnNext { out.flush() }
            .doOnNext { out.closeEntry() }
            .map { zipFile }
            .doOnComplete { out.close() }
            .log()
            .blockLast()
        )
}
于 2018-01-26T02:25:07.250 回答