2

Just started leaning Spring Reactive, and I couldn't find any examples on how to do something as simple as this. Without WebFlux, My controller was looking like this:

@GetMapping("/retrieveAttachment/{id}")
public ResponseEntity<byte[]> downloadFile(@PathVariable String id) throws Exception {
    Attachment attachment = documentManagerService.getAttachment(id);

    return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType("application/octet-stream"))
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + attachment.getFileName() + "\"")
            .body(attachment.getFileAttachment().getData());
}

Now with WebFlux, my documenManagerService returning Mono<Attachment>, this is what I came up with:

public Mono<ServerResponse> getAttachment(ServerRequest request) {
    Mono<byte[]> mono = documentManagerService.getAttachment(request.pathVariable("id"))
            .map(attachment -> attachment.getFileAttachment().getData());
    return ServerResponse
            .ok()
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM.toString())
            .body(mono, byte[].class);
}

I'm able to download the file, but the problem is the file is without extension since I've not set the Content Disposition Header. How do I set it without making a blocking call?

Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104

1 Answers1

3

By using flatMap maybe. Im writing this on mobile so have not tried it out or double checked anything.

public Mono<ServerResponse> getAttachment(ServerRequest request) {
    return documentManagerService.getAttachment(request.pathVariable("id"))
        .flatMap(attachment -> {
            return ServerResponse.ok()
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM.toString())
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + attachment.getFileName() + "\"")
                .bodyValue(attachment.getFileAttachment().getData())
        });
}
Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
  • 1
    tried but getting 'No serializer found for class org.springframework.web.reactive.function.server.DefaultEntityResponseBuilder$DefaultEntityResponse and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)' – Arvind Singh Jun 16 '22 at 06:01
  • You clearly have other problems in your code – Toerktumlare Jun 16 '22 at 09:16