Written by : Nguyen Quoc Thai
Gmail: thaithedoublecheese1@gmail.com

1. Tổng quát

Hướng dẫn nhanh này sẽ tập trung vào cách tải tệp nhiều phần lên bằng Spring’s RestTemplate. Chúng ta sẽ thấy cả một tệp duy nhất và nhiều tệp - tải lên bằng RestTemplate.

2. Thế nào là HTTP Multipart Request?

Nói một cách đơn giản, một request body HTTP POST cơ bản chứa dữ liệu biểu mẫu trong các cặp tên / giá trị. Mặt khác, các máy khách HTTP có thể xây dựng các yêu cầu nhiều phần HTTP để gửi các tệp văn bản hoặc tệp nhị phân đến máy chủ; nó chủ yếu được sử dụng để tải lên các tệp. Một trường hợp sử dụng phổ biến khác là gửi email có tệp đính kèm. Yêu cầu tệp nhiều phần chia một tệp lớn thành nhiều phần nhỏ hơn và sử dụng các điểm đánh dấu ranh giới để chỉ ra điểm bắt đầu và kết thúc của khối.

3. Thư viện Maven

với duy nhất dependency này là đủ cho ứng dụng khách:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

4. The File Upload Server

API máy chủ tệp hiển thị hai điểm cuối REST để tải lên các tệp đơn và nhiều tệp tương ứng:

  • POST /fileserver/singlefileupload/
  • POST /fileserver/multiplefileupload/

5. Uploading a Single File

Đầu tiên, hãy xem tải lên một tệp duy nhất bằng RestTemplate. Chúng ta cần tạo tiêu đề và nội dung HttpEntitywith. Đặt giá trị tiêu đề loại nội dung thành MediaType.MULTIPART_FORM_DATA. Khi tiêu đề này được đặt, RestTemplate sẽ tự động sắp xếp dữ liệu tệp cùng với một số siêu dữ liệu.

Siêu dữ liệu bao gồm tên tệp, kích thước tệp và loại nội dung tệp (ví dụ: văn bản / thuần túy):

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

Tiếp theo, xây dựng request body như một thể hiện của lớp LinkedMultiValueMap. LinkedMultiValueMap kết thúc LinkedHashMap lưu trữ nhiều giá trị cho mỗi khóa trong một LinkedList.
Trong ví dụ của chúng tôi, phương thức getTestFile () tạo một tệp giả một cách nhanh chóng và trả về một FileSystemResource:

MultiValueMap<String, Object> body
  = new LinkedMultiValueMap<>();
body.add("file", getTestFile());

Cuối cùng, xây dựng một cá thể HttpEntity bao bọc phần đầu và đối tượng body và đăng nó bằng cách sử dụng RestTemplate. Lưu ý rằng một tệp tải lên trỏ đến / fileserver / singlefileupload / endpoint.

Cuối cùng, lệnh gọi restTemplate.postForEntity () hoàn thành công việc kết nối với URL đã cho và gửi tệp đến máy chủ:

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);

Upload nhiều files

Trong quá trình tải lên nhiều tệp, thay đổi duy nhất so với tải lên một tệp duy nhất là trong việc tạo phần nội dung của yêu cầu. Hãy tạo nhiều tệp và thêm chúng bằng cùng một khóa trong MultiValueMap. Rõ ràng, URL yêu cầu phải tham chiếu đến điểm cuối để tải lên nhiều tệp:

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);

Kết luận

Cuối cùng, chúng tôi đã thấy một trường hợp truyền MultipartFile bằng Spring RestTemplate. Như mọi khi, mã nguồn máy khách và máy chủ mẫu có sẵn trên GitHub.

Link: https://github.com/eugenp/tutorials/tree/master/spring-web-modules/spring-resttemplate-3