🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
1. 多文件上传 + 混合表单参数
上传多个文件并附带其他表单参数(如用户ID、描述信息),且自定义文件名和 Content-Type。
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
public class AdvancedFileUpload {
public void uploadFilesWithMetadata() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://api.example.com/upload";
// 构造 multipart/form-data 请求体
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 添加文件参数(多个文件)
body.add("files", new FileSystemResource("path/to/file1.jpg") {
@Override
public String getFilename() {
return "custom-name-1.jpg"; // 自定义文件名
}
});
body.add("files", new FileSystemResource("path/to/file2.pdf"));
// 添加普通表单参数
body.add("userId", "12345");
body.add("description", "Project documents");
// 发送请求(自动处理 Content-Type 为 multipart/form-data)
String response = restTemplate.postForObject(url, body, String.class);
System.out.println("Response: " + response);
}
}
2. 动态设置文件元数据
通过 InputStreamResource
或 ByteArrayResource
动态设置文件的 Content-Type 和文件名。
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.io.ByteArrayInputStream;
public class FileMetadataExample {
public void uploadWithDynamicMetadata() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://api.example.com/upload";
// 从字节数组或流构造文件资源
byte[] fileData = "Hello, World!".getBytes();
ByteArrayResource resource = new ByteArrayResource(fileData) {
@Override
public String getFilename() {
return "dynamic-file.txt";
}
};
// 自定义 Content-Type
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new HttpEntity<>(resource, headers));
// 发送请求
String response = restTemplate.postForObject(url, body, String.class);
}
}
3. 大文件分块上传
处理大文件时,分块上传以减少内存占用,并支持断点续传。
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.StreamUtils;
import java.io.File;
import java.io.FileInputStream;
public class ChunkedFileUpload {
public void uploadLargeFileInChunks() throws Exception {
RestTemplate restTemplate = new RestTemplate();
String url = "http://api.example.com/upload-chunk";
File largeFile = new File("path/to/large-file.zip");
final int CHUNK_SIZE = 5 * 1024 * 1024; // 5MB per chunk
try (FileInputStream fis = new FileInputStream(largeFile)) {
byte[] buffer = new byte[CHUNK_SIZE];
int bytesRead;
int chunkNumber = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
// 截取实际读取的字节(避免最后一块填充空数据)
byte[] chunkData = new byte[bytesRead];
System.arraycopy(buffer, 0, chunkData, 0, bytesRead);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("chunk", new ByteArrayResource(chunkData) {
@Override
public String getFilename() {
return largeFile.getName() + ".part" + chunkNumber;
}
});
body.add("totalChunks", (int) Math.ceil(largeFile.length() / (double) CHUNK_SIZE));
body.add("chunkNumber", chunkNumber);
body.add("originalFilename", largeFile.getName());
restTemplate.postForObject(url, body, String.class);
chunkNumber++;
}
}
}
}
4. 处理文件上传响应及异常
捕获上传过程中的异常,并解析服务器返回的 JSON 数据。
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
public class ErrorHandlingExample {
public void uploadWithErrorHandling() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://api.example.com/upload";
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource("invalid-file.txt"));
try {
ResponseEntity<UploadResponse> response = restTemplate.postForEntity(
url,
new HttpEntity<>(body),
UploadResponse.class
);
if (response.getStatusCode().is2xxSuccessful()) {
UploadResponse result = response.getBody();
System.out.println("File URL: " + result.getFileUrl());
}
} catch (HttpClientErrorException e) {
System.err.println("Upload failed: " + e.getStatusCode());
System.err.println("Error details: " + e.getResponseBodyAsString());
}
}
static class UploadResponse {
private String fileUrl;
// Getters and Setters
}
}
5. 自定义请求头与认证
添加认证头(如 JWT)或自定义请求头。
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
public class AuthHeaderExample {
public void uploadWithAuth() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://api.example.com/secure-upload";
String token = "Bearer abc123";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("Authorization", token); // JWT 认证
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource("secret-doc.pdf"));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String response = restTemplate.postForObject(url, requestEntity, String.class);
}
}
关键注意事项
-
Content-Type 自动处理
RestTemplate
在发送MultiValueMap
时会自动设置Content-Type
为multipart/form-data
,无需手动指定。 -
资源释放
使用FileSystemResource
或InputStreamResource
时,确保及时关闭文件流(推荐用try-with-resources
)。 -
文件名编码
若文件名含特殊字符(如中文),需在客户端或服务端统一处理编码:String encodedFilename = URLEncoder.encode(rawFilename, StandardCharsets.UTF_8);
-
性能优化
- 大文件上传时,使用分块或流式传输避免内存溢出。
- 复用
RestTemplate
实例(通常配置为单例)。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙