Перейти к основному содержимому

Загрузить файл с помощью WebClient

· 2 мин. чтения

1. Обзор

Нашим приложениям часто приходится обрабатывать загрузку файлов через HTTP-запрос. Начиная с Spring 5, теперь мы можем сделать эти запросы реактивными.

Добавленная поддержка реактивного программирования позволяет нам работать неблокирующим образом, используя небольшое количество потоков и противодавление .

В этой статье мы будем использовать WebClient — неблокирующий реактивный HTTP-клиент — чтобы проиллюстрировать, как загрузить файл. WebClient является частью библиотеки реактивного программирования под названием Project Reactor . Мы рассмотрим два разных подхода к загрузке файла с помощью BodyInserter .

2. Загрузка файла с помощью WebClient

Чтобы использовать WebClient , нам нужно добавить в наш проект зависимость spring-boot-starter-webflux :

<dependency>
<groupId>org.springframework.boot</groupId>.
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2.1. Загрузка файла из ресурса

Для начала мы хотим объявить наш URL:

URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri();

Допустим, в этом примере мы хотим загрузить PDF. Мы будем использовать MediaType.APPLICATION_PDF в качестве ContentType .

Наша конечная точка загрузки возвращает HttpStatus. Поскольку мы ожидаем только один результат, мы обернем его в Mono :

Mono<HttpStatus> httpStatusMono = webClient.post()
.uri(url)
.contentType(MediaType.APPLICATION_PDF)
.body(BodyInserters.fromResource(resource))
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode());
} else {
throw new ServiceException("Error uploading file");
}
});

Метод, использующий этот метод, также может возвращать Mono , и мы можем продолжать до тех пор, пока нам действительно не понадобится доступ к результату. Когда мы будем готовы, мы можем вызвать метод block() для объекта Mono .

Метод fromResource() использует InputStream переданного ресурса для записи в выходное сообщение.

2.2. Загрузка файла из составного ресурса

Если наша внешняя конечная точка загрузки принимает данные формы Multipart, мы можем использовать MultiPartBodyBuilder , чтобы позаботиться о частях: ``

MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("file", multipartFile.getResource());

Здесь мы могли бы добавлять различные части в соответствии с нашими требованиями. Значение на карте может быть Object или HttpEntity.

Когда мы вызываем WebClient , мы используем BodyInsterter.fromMultipartData и строим объект:

.body(BodyInserters.fromMultipartData(builder.build()))

Мы обновляем тип контента до MediaType.MULTIPART_FORM_DATA , чтобы отразить изменения.

Давайте посмотрим на весь вызов:

Mono<HttpStatus> httpStatusMono = webClient.post()
.uri(url)
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(builder.build()))
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode());
} else {
throw new ServiceException("Error uploading file");
}
});

3. Заключение

В этом руководстве мы показали два способа загрузки файла с помощью WebClient с помощью BodyInserter s. Как всегда, код доступен на GitHub .