SpringBoot上传与下载文件
- 创业
- 2025-08-14 13:21:02

使用SpringBoot的虚拟路径映射。
Config中的类 import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * 图片绝对地址与虚拟地址映射 */ @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Value("${realityFileDepositPath}") private String realityFileDepositPath; @Value("${virtualFileDepositPath}") private String virtualFileDepositPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(virtualFileDepositPath) .addResourceLocations("file:" + realityFileDepositPath); } } Control中的类 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import xin.students.service.UpdateOrDownloadService; @RestController public class UpdateOrDownloadController { @Autowired UpdateOrDownloadService updateOrDownloadService; @PostMapping("/api/upload") public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) { return updateOrDownloadService.handleFileUpload(file); } @GetMapping("/api/upload/{fileName:.+}") public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) { return updateOrDownloadService.downloadFile(fileName); } } Service中的类 import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ContentDisposition; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.http.HttpHeaders; import java.io.File; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; @Service public class UpdateOrDownloadService { @Value("${virtualFileDepositPath}") private String virtualFileDepositPath; @Value("${realityFileDepositPath}") private String realityFileDepositPath; public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) { // 获取文件名 String fileName = file.getOriginalFilename(); // 确保文件名存在并且不是.exe文件 if (fileName != null && !fileName.toLowerCase().endsWith(".exe")) { fileName = System.currentTimeMillis() + fileName; // 检查文件大小是否合适 if (file.getSize() <= 10 * 1024 * 1024) { // 10 MB // 保存文件 try { String fullPath = realityFileDepositPath + fileName; file.transferTo(new File(fullPath)); System.out.println("Public document has been saved to: " + fullPath); } catch (IOException e) { e.printStackTrace(); return new ResponseEntity<>("Public document upload failed due to internal error", HttpStatus.INTERNAL_SERVER_ERROR); } // 返回文件访问虚拟路径 return new ResponseEntity<>(virtualFileDepositPath.substring(0, virtualFileDepositPath.length() - 2) + fileName, HttpStatus.OK); } else { return new ResponseEntity<>("Public document size exceeds 10MB", HttpStatus.BAD_REQUEST); } } else { // 提供一个不同的错误消息 return new ResponseEntity<>("Public document format is not supported or is executable, which is not allowed", HttpStatus.BAD_REQUEST); } } public ResponseEntity<Resource> downloadFile(String fileName) { try { // 确定文件的存储路径 Path filePath = Paths.get(realityFileDepositPath).resolve(fileName).normalize(); Resource resource = new UrlResource(filePath.toUri()); if(resource.exists() || resource.isReadable()) { // 确保文件名编码正确,避免乱码 String encodedFileName = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8.toString()); String contentDisposition = ContentDisposition.builder("attachment") .filename(encodedFileName, StandardCharsets.UTF_8) .build() .toString(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) .body(resource); } else { return ResponseEntity.notFound().build(); } } catch (IOException e) { // 如果无法读取文件,返回错误响应 return ResponseEntity.internalServerError().build(); } } } application.yml配置文件 virtualFileDepositPath: /api/image/** realityFileDepositPath: D:\xinFiles\ #结束必须要带/ 测试代码 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>文件上传和下载</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; flex-direction: column; } .container { text-align: center; } input[type="text"], input[type="file"] { margin: 10px 0; } </style> <script> function uploadFile() { var formData = new FormData(); var fileField = document.querySelector("input[type=file]"); formData.append('file', fileField.files[0]); fetch('/api/upload', { method: 'POST', body: formData }) .then(response => response.text()) .then(result => { alert('上传成功: ' + result); }) .catch(error => { console.error('上传出错:', error); alert('上传失败'); }); } function downloadFile() { var fileName = document.getElementById("filename").value; if (fileName) { window.open('/api/upload/' + fileName, '_blank'); } else { alert('请输入文件名'); } } </script> </head> <body> <div class="container"> <h1>文件上传</h1> <input type="file" id="fileInput"><br> <button onclick="uploadFile()">上传文件</button> <h1>文件下载</h1> <input type="text" id="filename" placeholder="请输入文件名"><br> <button onclick="downloadFile()">下载文件</button> </div> </body> </html>SpringBoot上传与下载文件由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“SpringBoot上传与下载文件”