import lombok.requiredargsconstructor;
import org.springframework.core.io.buffer.databuffer;
import org.springframework.core.io.buffer.databufferutils;
import org.springframework.stereotype.service;
import org.springframework.web.reactive.function.client.webclient;
import reactor.core.publisher.flux;
import reactor.core.publisher.mono;
import java.io.ioexception;
import java.nio.file.files;
import java.nio.file.path;
import java.nio.file.standardopenoption;
import java.util.objects;
@service
@requiredargsconstructor
public class filedownloaderwebclientservice {
private final webclient webclient;
/**
* reads the complete file in-memory. thus, only useful for very large file
*/
public void downloadusingbytearray(path destination) throws ioexception {
mono<byte[]> monocontents = webclient
.get()
.uri("/largefiles/1")
.retrieve()
.bodytomono(byte[].class);
files.write(destination, objects.requirenonnull(monocontents.share().block()),
standardopenoption.create);
}
/**
* reading file using mono will try to fit the entire file into the databuffer.
* results in exception when the file is larger than the databuffer capacity.
*/
public void downloadusingmono(path destination) {
mono databuffer = webclient
.get()
.uri("/largefiles/1")
.retrieve()
.bodytomono(databuffer.class);
databufferutils.write(databuffer, destination,
standardopenoption.create)
.share().block();
}
/**
* having using flux we can download files of any size safely.
* optionally, we can configure databuffer capacity for better memory utilization.
*/
public void downloadusingflux(path destination) {
flux databuffer = webclient
.get()
.uri("/largefiles/1")
.retrieve()
.bodytoflux(databuffer.class);
databufferutils.write(databuffer, destination,
standardopenoption.create)
.share().block();
}
}