文件上传与下载
在Spring Boot中实现文件上传与下载的功能通常涉及前端和后端的交互。前端负责提供文件选择的界面和触发上传/下载操作,后端则负责处理文件上传的请求、存储文件,以及处理文件下载的请求并发送文件内容给前端。
文件上传
- 前端:使用HTML表单或JavaScript库来选择文件并发送POST请求到后端。
- 后端:在Spring Boot中,你可以使用MultipartFile接口来处理文件上传。下面是一个简单的示例。
前端
<div class="container"><h1 class="title">文件上传</h1><form action="/uploadFile" enctype="multipart/form-data" method="post"><div class="upload-area"><input type="file" id="fileInput" name="files"multiple onchange="updateFileList(this)"><button type="submit" >上传文件</button></div><ul id="fileList" class="file-list"></ul></form><p id="uploadSuccess" class="upload-success" th:text="${uploadStatus}">文件上传成功!</p></div>
后端Controller示例:
实体表
@Data
@TableName("attachment")
public class Attachment {@TableId(type = IdType.AUTO)private Long id;private String fileName;private String storagePath;
}
上传页面访问方法
@Controller
public class FileController {@Autowiredprivate IAttachmentService attachmentService;// 向文件上传页面跳转@GetMapping("/toUpload")public String upload(){return "upload";}
}
文件上传方法
//文件上传管理@PostMapping("/uploadFile")public String uploadFile(MultipartFile[] files, Model model){// 默认文件上传成功,并返回状态信息model.addAttribute("uploadStatus", "上传成功!");for(MultipartFile file:files){// 获取文件名以及后缀名String fileName = file.getOriginalFilename();// 重新生成文件名(根据具体情况生成对应文件名)fileName = UUID.randomUUID()+"_"+fileName;// 指定上传文件本地存储目录,不存在需要提前创建String dirPath = "D:/file/";File filePath = new File(dirPath);if(!filePath.exists()){filePath.mkdirs();}try {file.transferTo(new File(dirPath+fileName));//文件信息存储到数据库中Attachment attachment = new Attachment();attachment.setFileName(file.getOriginalFilename());attachment.setStoragePath(fileName);attachmentService.save(attachment);} catch (Exception e) {e.printStackTrace();// 上传失败,返回失败信息model.addAttribute("uploadStatus","上传失败: "+e.getMessage());}}// 携带上传状态信息回调到文件上传页面return "upload";}
文件下载
前端:用户点击下载链接或按钮,触发GET请求到后端。
后端:在后端Controller中处理GET请求,读取文件内容,并将其作为HTTP响应返回给前端。
前端
<h1>文件下载列表</h1> <div class="file-list" ><div class="file-item" th:each="attachment:${list}"><p class="file-name" th:text="${attachment.fileName}">文件名1</p><a th:href="${'/download?id='+attachment.id}" class="download-button" download>下载</a></div><!-- 添加更多文件项 --> </div>
下载页面访问方法
/*** 向文件下载页面跳转*/@GetMapping("/toDownload")public String toDownload(Model model){//查询文件信息List<Attachment> list = attachmentService.list();model.addAttribute("list",list);return "download";}
文件下载方法
// 文件下载@GetMapping("/download")public ResponseEntity<Resource> fileDownload(HttpServletRequest request,Long id)throws Exception{//获取文件数据对象Attachment attachment = attachmentService.getById(id);// 指定要下载的文件根路径String dirPath = "D:/file/";// 创建该文件对象File file = new File(dirPath + attachment.getStoragePath());// 设置响应头HttpHeaders headers = new HttpHeaders();// 通知浏览器以下载方式打开(下载前对文件名进行转码)String filename=getFilename(request,attachment.getFileName());headers.setContentDispositionFormData("attachment",filename);// 定义以流的形式下载返回文件数据headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);InputStreamResource inputStreamResource =new InputStreamResource(Files.newInputStream(file.toPath()));return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);}
文件名乱码处理方法
// 根据浏览器的不同进行编码设置,返回编码后的文件名private String getFilename(HttpServletRequest request, String filename)throws Exception {// IE不同版本User-Agent中出现的关键词String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};// 获取请求头代理信息String userAgent = request.getHeader("User-Agent");for (String keyWord : IEBrowserKeyWords) {if (userAgent.contains(keyWord)) {//IE内核浏览器,统一为UTF-8编码显示,并对转换的+进行更正return URLEncoder.encode(filename, "UTF-8").replace("+"," ");}}//火狐等其它浏览器统一为ISO-8859-1编码显示return new String(filename.getBytes("UTF-8"), "ISO-8859-1");}
效果测试
文件上传
文件下载页面