diff --git a/src/main/java/cn/somkit/fmt/action/DownloadAction.java b/src/main/java/cn/somkit/fmt/action/DownloadAction.java index 6a11a33..a59f015 100644 --- a/src/main/java/cn/somkit/fmt/action/DownloadAction.java +++ b/src/main/java/cn/somkit/fmt/action/DownloadAction.java @@ -8,18 +8,24 @@ import cn.somkit.fmt.utils.RocksDBUtils; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.CollectionUtils; import org.springframework.util.FileSystemUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -98,32 +104,45 @@ public class DownloadAction { return mv; } - @RequestMapping("/execute") - @ApiOperate(description = "单文件下载") - public void execute(String path, Boolean temp, HttpServletResponse response) throws Exception { - File file = new File(path); - if (!file.isFile()) { - throw new FileNotFoundException("文件不存在"); + @ApiOperate(description = "StreamingResponseBody方式下载文件") + @GetMapping(value = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + public DeferredResult> downloadFileByPath(String path, Boolean temp) throws Exception { + final File file = new File(path); + final DeferredResult> result = new DeferredResult<>(); + + if (!file.exists()) { + result.setErrorResult(new RuntimeException("文件不存在")); + return result; } - String filename = file.getName(); - response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8)); - response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(file.length())); - try (FileInputStream fileInputStream = new FileInputStream(file); - BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); - BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(response.getOutputStream())) { - byte[] buffer_ = new byte[1024]; - int n = bufferedInputStream.read(buffer_); - while (n != -1) { - bufferedOutputStream.write(buffer_); - n = bufferedInputStream.read(buffer_); + + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8)); + headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(file.length())); + StreamingResponseBody body = outputStream -> { + try (InputStream inputStream = new FileInputStream(file)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.flush(); + } catch (IOException e) { + throw new RuntimeException("IO错误: " + e.getMessage()); + } finally { + // 尝试在流关闭后删除文件 + try { + if(temp){ + Files.deleteIfExists(file.toPath()); + } + } catch (IOException e) { + // 记录日志或采取其他措施 + System.err.println("删除文件失败: " + e.getMessage()); + } } - } catch (Exception e) { - e.printStackTrace(); - } finally { - if(temp){//删除临时文件 - FileSystemUtils.deleteRecursively(new File(path)); - } - } + }; + + result.setResult(new ResponseEntity<>(body, headers, HttpStatus.OK)); + return result; } @PostMapping("/packZip") diff --git a/src/main/resources/templates/download.html b/src/main/resources/templates/download.html index 6a67abc..3acd61a 100644 --- a/src/main/resources/templates/download.html +++ b/src/main/resources/templates/download.html @@ -104,7 +104,7 @@ const fileDown = (obj) => { const path = obj.getAttribute("value"); - window.open(Fmt.ctx() + '/download/execute?path=' + encodeURIComponent(path) + '&temp=' + false); + window.open(Fmt.ctx() + '/download/file?path=' + encodeURIComponent(path) + '&temp=' + false); }; window.onload = () => {