wenj you hua
This commit is contained in:
@@ -41,66 +41,56 @@ public class FileController extends BaseController {
|
||||
// 检查用户登录状态
|
||||
|
||||
// 获取文件字节
|
||||
if (objectName.equals("musicFile")) {
|
||||
LoginUser userInfo = SecurityUtils.getLoginUser();
|
||||
if (userInfo == null){
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
|
||||
return;
|
||||
}
|
||||
SysUser sysUser = userInfo.getUser();
|
||||
if (sysUser == null) {
|
||||
if (StrUtil.isBlank(musicId)) {
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":400,\"msg\":\"音乐ID不能为空\"}");
|
||||
return;
|
||||
}
|
||||
ShopUser shopUser = userInfo.getShopUser();
|
||||
if (shopUser == null) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
|
||||
return;
|
||||
}
|
||||
//shopUser = shopUserMapper.selectShopUserByUserId(userId);
|
||||
MusicInfo musicInfo = musicInfoMapper.selectByMusicId(musicId);
|
||||
|
||||
if (musicInfo == null) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":404,\"msg\":\"音乐信息不存在\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (musicInfo.getVip() != null && musicInfo.getVip() == 1) {
|
||||
// 判断用户vip
|
||||
if (!MusicUtil.getShopIsVip(shopUser)) {
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":403,\"msg\":\"该音乐为VIP专享,请升级VIP后下载\"}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] data = AliConfig.ossDown(ossPath);
|
||||
if (data == null || data.length == 0) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在或下载失败\"}");
|
||||
return;
|
||||
}
|
||||
// if (objectName.equals("musicFile")) {
|
||||
// LoginUser userInfo = SecurityUtils.getLoginUser();
|
||||
// if (userInfo == null){
|
||||
// response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
// response.setContentType("application/json;charset=UTF-8");
|
||||
// response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
|
||||
// return;
|
||||
// }
|
||||
// SysUser sysUser = userInfo.getUser();
|
||||
// if (sysUser == null) {
|
||||
// if (StrUtil.isBlank(musicId)) {
|
||||
// response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
// response.setContentType("application/json;charset=UTF-8");
|
||||
// response.getWriter().write("{\"code\":400,\"msg\":\"音乐ID不能为空\"}");
|
||||
// return;
|
||||
// }
|
||||
// ShopUser shopUser = userInfo.getShopUser();
|
||||
// if (shopUser == null) {
|
||||
// response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
// response.setContentType("application/json;charset=UTF-8");
|
||||
// response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
|
||||
// return;
|
||||
// }
|
||||
// //shopUser = shopUserMapper.selectShopUserByUserId(userId);
|
||||
// MusicInfo musicInfo = musicInfoMapper.selectByMusicId(musicId);
|
||||
//
|
||||
// if (musicInfo == null) {
|
||||
// response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
// response.setContentType("application/json;charset=UTF-8");
|
||||
// response.getWriter().write("{\"code\":404,\"msg\":\"音乐信息不存在\"}");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (musicInfo.getVip() != null && musicInfo.getVip() == 1) {
|
||||
// // 判断用户vip
|
||||
// if (!MusicUtil.getShopIsVip(shopUser)) {
|
||||
// response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
// response.setContentType("application/json;charset=UTF-8");
|
||||
// response.getWriter().write("{\"code\":403,\"msg\":\"该音乐为VIP专享,请升级VIP后下载\"}");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 设置响应头
|
||||
String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
|
||||
if (fileExtension.equals("mp3")) {
|
||||
// 对于MP3文件,设置为音频流,支持直接播放
|
||||
response.setContentType("audio/mpeg");
|
||||
// 设置内容长度
|
||||
response.setContentLength(data.length);
|
||||
// 允许范围请求,支持断点续传
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
// 不设置Content-Disposition,这样浏览器会直接播放而不是下载
|
||||
@@ -109,9 +99,23 @@ public class FileController extends BaseController {
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
|
||||
}
|
||||
|
||||
// 设置缓冲区大小和连接保持
|
||||
response.setBufferSize(8192); // 8KB缓冲区
|
||||
response.setHeader("Connection", "Keep-Alive");
|
||||
|
||||
try {
|
||||
response.getOutputStream().write(data);
|
||||
response.getOutputStream().flush();
|
||||
// 使用流式下载而不是一次性加载全部内容到内存
|
||||
boolean success = AliConfig.ossDownloadStream(ossPath, response.getOutputStream());
|
||||
if (!success) {
|
||||
if (!response.isCommitted()) {
|
||||
response.reset();
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在或下载失败\"}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// 检查是否为客户端断开连接的错误(Broken pipe)
|
||||
if (e.getMessage() != null &&
|
||||
|
||||
@@ -160,4 +160,100 @@ public class AliConfig {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式下载OSS文件,直接写入输出流,避免一次性加载整个文件到内存
|
||||
*
|
||||
* @param objectName OSS对象名称
|
||||
* @param outputStream 输出流
|
||||
* @return 是否下载成功
|
||||
*/
|
||||
public static boolean ossDownloadStream(String objectName, java.io.OutputStream outputStream) {
|
||||
// 配置参数
|
||||
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
|
||||
String accessKeyId = AliKeyConfig.ACCESS_KEY_ID;
|
||||
String accessKeySecret = AliKeyConfig.ACCESS_KEY_SECRET;
|
||||
String bucketName = "wenzhuangmusic";
|
||||
|
||||
OSS ossClient = null;
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
|
||||
// 判断文件是否存在
|
||||
boolean exists = ossClient.doesObjectExist(bucketName, objectName);
|
||||
if (!exists) {
|
||||
log.error("OSS文件不存在: {}", objectName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取文件对象
|
||||
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
|
||||
inputStream = ossObject.getObjectContent();
|
||||
|
||||
// 使用缓冲区进行流式传输
|
||||
byte[] buffer = new byte[8192]; // 8KB缓冲区
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
try {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
// 定期刷新输出流,避免缓冲区溢出
|
||||
if (bytesRead == buffer.length) {
|
||||
outputStream.flush();
|
||||
}
|
||||
} catch (java.io.IOException e) {
|
||||
// 检查是否为客户端断开连接的错误
|
||||
if (e.getMessage() != null &&
|
||||
(e.getMessage().contains("Broken pipe") ||
|
||||
e.getMessage().contains("Connection reset by peer") ||
|
||||
e.getMessage().contains("连接被对方重置") ||
|
||||
e.getMessage().contains("你的主机中的软件中止了一个已建立的连接") ||
|
||||
e.getMessage().contains("Software caused connection abort") ||
|
||||
e.getMessage().contains("SocketTimeoutException"))) {
|
||||
// 客户端已断开连接,记录日志但不作为错误处理
|
||||
log.info("客户端断开连接,文件传输中断: {}", e.getMessage());
|
||||
return true; // 返回true,因为这不是服务器端的错误
|
||||
} else {
|
||||
// 其他IO错误,重新抛出
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
outputStream.flush();
|
||||
return true;
|
||||
} catch (java.io.IOException e) {
|
||||
// 检查是否为客户端断开连接的错误
|
||||
if (e.getMessage() != null &&
|
||||
(e.getMessage().contains("Broken pipe") ||
|
||||
e.getMessage().contains("Connection reset by peer") ||
|
||||
e.getMessage().contains("连接被对方重置") ||
|
||||
e.getMessage().contains("你的主机中的软件中止了一个已建立的连接") ||
|
||||
e.getMessage().contains("Software caused connection abort") ||
|
||||
e.getMessage().contains("SocketTimeoutException"))) {
|
||||
// 客户端已断开连接,记录日志但不作为错误处理
|
||||
log.info("客户端断开连接,文件传输中断: {}", e.getMessage());
|
||||
return true; // 返回true,因为这不是服务器端的错误
|
||||
} else {
|
||||
// 其他IO错误
|
||||
log.error("下载OSS文件失败: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载OSS文件失败: {}", e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
// 关闭资源
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (java.io.IOException e) {
|
||||
log.error("关闭输入流失败: {}", e.getMessage());
|
||||
}
|
||||
|
||||
if (ossClient != null) {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="selectShareInfoListPage" resultType="com.ruoyi.common.core.domain.entity.ShareInfo">
|
||||
SELECT
|
||||
si.id as id,
|
||||
si.share_num as shareNum,
|
||||
su.username as username,
|
||||
su.nickname as nickname,
|
||||
su.head_img as headImg,
|
||||
|
||||
Reference in New Issue
Block a user