日光、空气和清水,锻炼身体三件宝。——佚名
在现代 Web 开发中,处理文件上传是一个常见需求。本文将分享一个完整的解决方案,包括使用 HTML FormData 发送文件和 Spring Boot 接收及转发的实现。
以下是 HTML 和 JavaScript 代码示例,用于选择文件并通过 FormData 将其发送到服务器。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 | <!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 实现代码。该代码接收文件后,将文件及其他参数转发到目标服务。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 | @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
和其他参数。RestTemplate
将接收到的文件和参数转发到目标服务。MultipartFileResource
以适配 Spring 的资源接口。http://127.0.0.1:8200/chat_server
。FormData
方便地组织并发送文件和其他数据。这套实现适合需要在前后端协作下处理复杂文件上传的场景,如音频处理、图片识别等。