Downloading file using Spring Webclient, file is empty
Asked Answered
S

1

7

I'm supposed to download a ZIP file from 3rd party API. However, when I'm using Spring Webclient I end up with an empty file. Any ideas what I'm doing wrong? What is the proper way to store the content of Flux<DataBuffer> to a file?

Here's my code:

WebClient client = WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient1))
            .baseUrl(String.format(FILE_DOWNLOAD_PATH))
            .build();


    WebClient.RequestBodyUriSpec method = client.method(HttpMethod.GET);
    method.header("Authorization", "Bearer " + accessToken);
    final Flux<DataBuffer> dataBufferFlux = method.retrieve().bodyToFlux(DataBuffer.class);

    final Path path = FileSystems.getDefault().getPath("example" + new Random(200).nextInt() + ".zip");

    WritableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
    Mono<Path> then = DataBufferUtils.write(dataBufferFlux, channel)
            .map(DataBufferUtils::release)
            .then(Mono.just(path));

UPDATE: The above code is being called directly from main, and then the application shuts down. Could this be an issue?

Smoke answered 14/7, 2020 at 15:4 Comment(4)
If that don't throw an exception, the problem is the REST Api you are callingYockey
@AL it doesn't throw an exception, it just creates an empty .zip file. I'm able to download the file from this API using POSTMAN, so the API itself works just fineSmoke
As for your update - remember that nothing happens until you subscribe. Usually with spring the framework will subscribe for you, but obviously that doesn't apply if you're not using a framework controlled method. Try calling block() on your then variable.Contemporary
Hey @Smoke .It's been quite a while since you posted this question. Any updates from your side? Did you try out the answer I provided ?Banc
B
8

As @MichaelBerry mentioned, you are missing the block call.

It is clearly mentioned in the method documentation that:

Note that the writing process does not start until the returned Flux is subscribed to.

Below code worked for me:

public class MySpringBootApp {

  public static void main(String[] args) throws IOException {

    Path path = Paths.get("src/main/resources/sample.zip");
    WebClient client = WebClient.builder()
        .baseUrl("https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip")
        .build();
    Flux<DataBuffer> dataBufferFlux = client.get().retrieve().bodyToFlux(DataBuffer.class);
    DataBufferUtils.write(dataBufferFlux, path, StandardOpenOption.CREATE).block(); //Creates new file or overwrites exisiting file

  }


}
Banc answered 15/7, 2020 at 13:49 Comment(1)
Is there a way to save the file with its original name received in response?Jellied

© 2022 - 2024 — McMap. All rights reserved.