springBoot文件上传、下载
文件上传
1. 项目环境准备
首先要确保你的项目中已经添加了必要的依赖。如果你使用的是Maven项目,在pom.xml
文件里添加以下依赖:
<dependencies><!-- Spring Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 用于处理文件上传的Commons FileUpload和Commons IO --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>
</dependencies>
2. 配置文件上传解析器
在Spring Boot项目中,Spring Boot会自动配置一个MultipartConfigElement
,你只需在application.properties
或application.yml
中进行简单配置:
# 设置最大文件上传大小
spring.servlet.multipart.max-file-size=10MB
# 设置最大请求大小
spring.servlet.multipart.max-request-size=10MB
# 开启文件上传支持
spring.servlet.multipart.enabled=true
3. 处理文件上传请求
public Result upload(MultipartFile file, String userCode) {if (file.isEmpty()) {return Result.error("文件为空");} else {try {// 获取文件原始名称String originalFilename = file.getOriginalFilename();// 指定文件存储的路径// 获取当前时间LocalDate currentDate = LocalDate.now();DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM");String dirPath = "D:/uploads/" + currentDate.format(formatter1) + '/';// 生成新的文件名String newFileName = System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));String filePath = dirPath + newFileName;// 将文件保存的文件目录下File file1 = new File(filePath);if (!file1.getParentFile().exists()) {file1.getParentFile().mkdirs();}// 将文件保存到指定目录下file.transferTo(file1);// 记录上传的文件到数据库中SysFile sysFile = new SysFile();sysFile.setFileName(originalFilename);sysFile.setFilePath(filePath);sysFile.setFileExtension(originalFilename.substring(originalFilename.lastIndexOf(".") + 1));// 转换为MB,保留小数点后3位小数float fileSize = file.getSize() / (1024f * 1024f);String formattedValue = String.format("%.3f", fileSize);sysFile.setFileSize(Float.parseFloat(formattedValue));sysFile.setCreateAt(LocalDateTime.now());sysFile.setUserCode(userCode);sysFileDao.insert(sysFile);// 返回文件信息return Result.success(sysFile);} catch (Exception e) {System.out.println("文件上传失败:" + e.getMessage());return Result.error("文件上传失败");}}}
文件下载
Controller层
@Operation(summary = "文件下载")@PostMapping("fileDownload")public void fileDownload(@Valid @RequestBody IdList idList, HttpServletResponse response) throws IOException {fileService.fileDownload(idList.getIdList(),response);}
Service层
public void fileDownload(List<String> idList, HttpServletResponse response) throws IOException {// 1、判断数据库中是否存在这些文件LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.in(SysFile::getId, idList);if (sysFileDao.exists(queryWrapper)) {// 获取文件信息List<SysFile> fileList = sysFileDao.selectList(queryWrapper);if (idList.size() == 1) {// 单文件下载this.downloadSingleFile(fileList.get(0).getFilePath(), response);} else {// 多文件下载this.downloadMultipleFilesAsZip(fileList, response);}} else {// 抛出异常throw new RuntimeException("存在不存在的文件");}}// 单文件下载private void downloadSingleFile(String filePath, HttpServletResponse response) throws IOException {File file = new File(filePath);if (file.exists()) {response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));response.setContentLength((int) file.length());try (InputStream in = new FileInputStream(file);OutputStream out = response.getOutputStream()) {byte[] buffer = new byte[4096];int length;while ((length = in.read(buffer)) > 0) {out.write(buffer, 0, length);}}}}// 多文件下载private void downloadMultipleFilesAsZip(List<SysFile> fileInfos, HttpServletResponse response) throws IOException {response.setContentType("application/zip");response.setHeader("Content-Disposition", "attachment;filename=files.zip");try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {for (SysFile fileInfo : fileInfos) {File file = new File(fileInfo.getFilePath());if (file.exists()) {try (FileInputStream fileIn = new FileInputStream(file)) {ZipEntry zipEntry = new ZipEntry(file.getName());zipOut.putNextEntry(zipEntry);byte[] buffer = new byte[4096];int length;while ((length = fileIn.read(buffer)) > 0) {zipOut.write(buffer, 0, length);}zipOut.closeEntry();}}}}}