日光、空气和清水,锻炼身体三件宝。——佚名
在现代 Web 开发中,处理文件上传是一个常见需求。本文将分享一个完整的解决方案,包括使用 HTML FormData 发送文件和 Spring Boot 接收及转发的实现。
以下是 HTML 和 JavaScript 代码示例,用于选择文件并通过 FormData 将其发送到服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>File Upload</title> </head> <body> <h1>File Upload with Base64 Encoding</h1> <form id="uploadForm"> <label for="audioFile">Select Audio File (wav):</label><br> <input type="file" id="audioFile" name="audio" accept="audio/wav"><br><br>
<label for="imageFile">Select Image File (jpg):</label><br> <input type="file" id="imageFile" name="image" accept="image/jpeg"><br><br>
<button type="button" onclick="sendFiles()">Upload</button> </form>
<script> async function sendFiles() { const audioFile = document.getElementById('audioFile').files[0]; const imageFile = document.getElementById('imageFile').files[0];
if (!audioFile || !imageFile) { alert('Please select both files.'); return; }
const formData = new FormData(); formData.append('audio', audioFile); formData.append('device_id', "ddd");
try { const imageBase64 = await convertFileToBase64(imageFile); const base64Clean = imageBase64.split(',')[1]; formData.append('image', base64Clean);
const response = await fetch('http://127.0.0.1:11010/chat_server', { method: 'POST', body: formData, });
if (!response.ok) { const errorText = await response.text(); throw new Error(`Server responded with ${response.status}: ${errorText}`); }
const result = await response.json(); console.log(`Upload successful: ${JSON.stringify(result)}`); } catch (error) { console.error('Error:', error); alert(`Upload failed: ${error.message}`); } }
function convertFileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(file); }); } </script> </body> </html>
|
说明:
FormData
用于构建要发送到服务器的键值对。
FileReader
用于将图像文件转换为 Base64 编码。
- 文件通过
fetch
POST 到指定的 Spring Boot 服务器端点。
后端部分:Spring Boot 接收并转发文件
以下是后端的 Spring Boot 实现代码。该代码接收文件后,将文件及其他参数转发到目标服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| @RestController @RequestMapping("/chat_server") public class ChatController {
@PostMapping public ResponseEntity<Map<String, Object>> forwardFiles( @RequestParam("audio") MultipartFile audioFile, @RequestParam("image") String imageBase64, @RequestParam("device_id") String device_id) {
Map<String, Object> response = new HashMap<>(); try { var targetResponse = forwardToTargetService(audioFile, imageBase64, device_id); if (targetResponse.getStatusCode().is2xxSuccessful()) { response.put("message", "Files forwarded successfully"); response.put("targetResponse", targetResponse.getBody()); return ResponseEntity.ok(response); } else { response.put("message", "Error forwarding files to target service"); return ResponseEntity.status(targetResponse.getStatusCode()).body(response); } } catch (Exception e) { response.put("message", "Error: " + e.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } }
private ResponseEntity<List<String>> forwardToTargetService( MultipartFile audioFile, String imageBase64, String device_id) throws Exception {
RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("audio", new MultipartFileResource(audioFile)); body.add("image", imageBase64);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers); String TARGET_URL = "http://127.0.0.1:8200/chat_server?device_id=" + device_id;
return restTemplate.exchange( TARGET_URL, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<>() {} ); }
private static class MultipartFileResource extends org.springframework.core.io.ByteArrayResource { private final MultipartFile file;
public MultipartFileResource(MultipartFile file) throws Exception { super(file.getBytes()); this.file = file; }
@Override public String getFilename() { return this.file.getOriginalFilename(); } } }
|
关键点:
-
接收数据:
- 使用
@RequestParam
注解接收 MultipartFile
和其他参数。
- 图像以 Base64 编码字符串形式传递。
-
转发数据:
- 通过
RestTemplate
将接收到的文件和参数转发到目标服务。
- 自定义
MultipartFileResource
以适配 Spring 的资源接口。
-
目标服务 URL:
- 转发目标地址
http://127.0.0.1:8200/chat_server
。
总结
- 前端使用
FormData
方便地组织并发送文件和其他数据。
- 后端通过 Spring Boot 灵活接收和转发文件,满足不同场景需求。
这套实现适合需要在前后端协作下处理复杂文件上传的场景,如音频处理、图片识别等。