1. Обзор
В этом кратком руководстве основное внимание уделяется тому, как загрузить составной файл с помощью Spring RestTemplate.
Мы увидим как один файл, так и несколько файлов — загрузите с помощью RestTemplate.
2. Что такое составной HTTP-запрос?
Проще говоря, базовое тело запроса HTTP POST содержит данные формы в парах имя/значение.
С другой стороны, HTTP-клиенты могут создавать составные HTTP-запросы для отправки текстовых или двоичных файлов на сервер; он в основном используется для загрузки файлов.
Другим распространенным вариантом использования является отправка электронного письма с вложением. Запросы файлов, состоящих из нескольких частей, разбивают большой файл на более мелкие фрагменты и используют граничные маркеры для обозначения начала и конца блока.
Узнайте больше о составных запросах здесь .
3. Зависимость от Maven
Этой единственной зависимости достаточно для клиентского приложения:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
4. Сервер загрузки файлов
API файлового сервера предоставляет две конечные точки REST для загрузки одного и нескольких файлов соответственно:
POST /файловый сервер/загрузка одного файла/
POST /fileserver/multiplefileupload/
5. Загрузка одного файла
Во-первых, давайте посмотрим на загрузку одного файла с помощью RestTemplate.
Нам нужно создать HttpEntity
с заголовком и телом. Задайте для заголовка типа содержимого
значение MediaType.MULTIPART_FORM_DATA
. Когда этот заголовок установлен, RestTemplate
автоматически упорядочивает данные файла вместе с некоторыми метаданными.
Метаданные включают имя файла, размер файла и тип содержимого файла (например, text/plain
):
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
Затем создайте тело запроса как экземпляр класса LinkedMultiValueMap
. LinkedMultiValueMap
обертывает LinkedHashMap
, сохраняя несколько значений для каждого ключа в LinkedList
.
В нашем примере метод getTestFile()
создает фиктивный файл на лету и возвращает FileSystemResource
:
MultiValueMap<String, Object> body
= new LinkedMultiValueMap<>();
body.add("file", getTestFile());
Наконец, создайте экземпляр HttpEntity
, который упаковывает заголовок и объект тела, и опубликуйте его с помощью RestTemplate
.
Обратите внимание, что загрузка одного файла указывает на конечную точку /fileserver/singlefileupload/
.
В конце концов, вызов restTemplate.postForEntity()
завершает работу по соединению с заданным URL и отправке файла на сервер:
HttpEntity<MultiValueMap<String, Object>> requestEntity
= new HttpEntity<>(body, headers);
String serverUrl = "http://localhost:8082/spring-rest/fileserver/singlefileupload/";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate
.postForEntity(serverUrl, requestEntity, String.class);
6. Загрузка нескольких файлов
При загрузке нескольких файлов единственное отличие от загрузки одного файла заключается в построении тела запроса.
Давайте создадим несколько файлов и добавим их с одним и тем же ключом в MultiValueMap
.
Очевидно, URL-адрес запроса должен ссылаться на конечную точку для загрузки нескольких файлов:
MultiValueMap<String, Object> body
= new LinkedMultiValueMap<>();
body.add("files", getTestFile());
body.add("files", getTestFile());
body.add("files", getTestFile());
HttpEntity<MultiValueMap<String, Object>> requestEntity
= new HttpEntity<>(body, headers);
String serverUrl = "http://localhost:8082/spring-rest/fileserver/multiplefileupload/";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate
.postForEntity(serverUrl, requestEntity, String.class);
Всегда можно смоделировать загрузку одного файла, используя загрузку нескольких файлов.
7. Заключение
В заключение мы увидели случай переноса MultipartFile
с использованием Spring RestTemplate
.
Как всегда, пример исходного кода клиента и сервера доступен на GitHub .