2

I am new in Spring 5 and Reactive Programming. My problem is creating the export feature for the database by a rest API. User hits GET request -> Server reads data and returns data as a zip file. Because zip file is large, so I need to stream these data. My code as below:

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

I use curl as below:

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

But it always returns 406 Not Acceptable. Anyone helps?

Thank you so much

FinalDest
  • 49
  • 2
  • 7

2 Answers2

0

The headers attribute of the @GetMapping annotation are not headers that should be written to the HTTP response, but mapping headers. This means that your @GetMapping annotation requires the HTTP request to contain the headers you've listed. This is why the request is actually not mapped to your controller handler.

Now your handler return type does not look right - Flux<Resource> means that you intend to return 0..* Resource instances and that they should be serialized. In this case, a return type like ResponseEntity<Resource> is probably a better choice since you'll be able to set response headers on the ResponseEntity and set its body with a Resource.

Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
  • I understood your point. But my service returns Flux. How can I transfer it to JSON files and put all in a result.zip file? Thank you – FinalDest Jan 25 '18 at 01:32
-1

Is it right, man? I still feel it's not good with this solution at the last line when using 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()
        )
}
FinalDest
  • 49
  • 2
  • 7