修改文件下载方式,使用StreamingResponseBody,支持大文件下载
This commit is contained in:
@@ -9,18 +9,24 @@ import cn.somkit.fmt.utils.PathUtils;
|
||||
import cn.somkit.fmt.utils.RocksDBUtils;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
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;
|
||||
@@ -91,32 +97,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<ResponseEntity<StreamingResponseBody>> downloadFileByPath(String path, Boolean temp) throws Exception {
|
||||
final File file = new File(path);
|
||||
final DeferredResult<ResponseEntity<StreamingResponseBody>> 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);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
outputStream.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("IO错误: " + e.getMessage());
|
||||
} finally {
|
||||
if(temp){//删除临时文件
|
||||
FileSystemUtils.deleteRecursively(new File(path));
|
||||
// 尝试在流关闭后删除文件
|
||||
try {
|
||||
if(temp){
|
||||
Files.deleteIfExists(file.toPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// 记录日志或采取其他措施
|
||||
System.err.println("删除文件失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result.setResult(new ResponseEntity<>(body, headers, HttpStatus.OK));
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/packZip")
|
||||
|
||||
@@ -108,7 +108,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 = () => {
|
||||
@@ -139,7 +139,7 @@
|
||||
};
|
||||
Fmt.axios(options).then((result) => {
|
||||
message.update({content: '压缩包' + result.filename + "创建完成,准备下载文件......", result: 'success'}).show();
|
||||
window.open(Fmt.ctx() + '/download/execute?path=' + encodeURIComponent(result.path) + '&temp=' + true);
|
||||
window.open(Fmt.ctx() + '/download/file?path=' + encodeURIComponent(result.path) + '&temp=' + true);
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
new axMessage({content: err, result: 'error', iconShow: true}).show();
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
修改上传文件目录配置,使其支持使用相对路径
|
||||
新增临时文件存放地址配置,支持相对路径
|
||||
新增系统设置页面,支持在线配置上传文件地址、日志文件地址等参数
|
||||
修改文件下载方式,使用StreamingResponseBody,支持大文件下载
|
||||
```
|
||||
Reference in New Issue
Block a user