mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-18 17:38:48 +08:00
add 新增异步流下载方式
This commit is contained in:
parent
ad6b3d4b3f
commit
8113579a5b
@ -2,6 +2,8 @@ package org.dromara.system.controller.system;
|
||||
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.QueryGroup;
|
||||
@ -18,9 +20,11 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@ -92,6 +96,19 @@ public class SysOssController extends BaseController {
|
||||
ossService.download(ossId, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载OSS对象(使用非阻塞流方式)
|
||||
*
|
||||
* @param ossId OSS对象ID
|
||||
*/
|
||||
@SaIgnore
|
||||
@GetMapping("/streaming/download/{ossId}")
|
||||
public ResponseEntity<StreamingResponseBody> download(@PathVariable Long ossId) {
|
||||
// 该方法是异步处理方法 SaToken 的权限注解不支持异步与同步混用,会报异常,但不影响正常的下载,此处手动校验即可
|
||||
StpUtil.checkPermission("system:oss:download");
|
||||
return ossService.streamingDownload(ossId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除OSS对象存储
|
||||
*
|
||||
|
||||
@ -5,7 +5,9 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.system.domain.bo.SysOssBo;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -68,6 +70,13 @@ public interface ISysOssService {
|
||||
*/
|
||||
void download(Long ossId, HttpServletResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* 非阻塞流下载方法
|
||||
*
|
||||
* @param ossId OSS对象ID
|
||||
*/
|
||||
ResponseEntity<StreamingResponseBody> streamingDownload(Long ossId);
|
||||
|
||||
/**
|
||||
* 删除OSS对象存储
|
||||
*
|
||||
|
||||
@ -21,6 +21,7 @@ import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.oss.core.OssClient;
|
||||
import org.dromara.common.oss.core.WriteOutSubscriber;
|
||||
import org.dromara.common.oss.entity.UploadResult;
|
||||
import org.dromara.common.oss.enums.AccessPolicyType;
|
||||
import org.dromara.common.oss.factory.OssFactory;
|
||||
@ -32,12 +33,16 @@ import org.dromara.system.mapper.SysOssMapper;
|
||||
import org.dromara.system.service.ISysOssService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -183,6 +188,33 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
|
||||
storage.download(sysOss.getFileName(), response.getOutputStream(), response::setContentLengthLong);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非阻塞流下载方法
|
||||
*
|
||||
* @param ossId OSS对象ID
|
||||
*/
|
||||
@Override
|
||||
public ResponseEntity<StreamingResponseBody> streamingDownload(Long ossId) {
|
||||
SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
|
||||
if (ObjectUtil.isNull(sysOss)) {
|
||||
throw new ServiceException("文件数据不存在!");
|
||||
}
|
||||
OssClient storage = OssFactory.instance(sysOss.getService());
|
||||
|
||||
// 构建响应体
|
||||
String percentEncodedFileName = FileUtils.percentEncode(sysOss.getOriginalName());
|
||||
String contentDispositionValue = "attachment; filename=%s;filename*=utf-8''%s".formatted(percentEncodedFileName, percentEncodedFileName);
|
||||
ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.ok()
|
||||
.header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "Content-Disposition,download-filename")
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, contentDispositionValue)
|
||||
.header("download-filename", percentEncodedFileName)
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
// 获取写出流订阅器
|
||||
WriteOutSubscriber<OutputStream> subscriber = storage.download(sysOss.getFileName(), bodyBuilder::contentLength);
|
||||
return bodyBuilder.body(subscriber::writeTo);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库
|
||||
*
|
||||
@ -197,7 +229,7 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
|
||||
OssClient storage = OssFactory.instance();
|
||||
UploadResult uploadResult;
|
||||
try {
|
||||
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
|
||||
uploadResult = storage.uploadSuffix(file.getInputStream(), suffix, file.getSize(), file.getContentType());
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user