|
|
@@ -79,37 +79,54 @@ public class FileTypeUtils {
|
|
|
* @param content 内容(完整或分片)
|
|
|
*/
|
|
|
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
|
|
|
- // 1. 基础头设置
|
|
|
- String contentType = getMineType(content, filename);
|
|
|
-
|
|
|
- // 2. 设置响应头(根据文件类型)
|
|
|
-// if (filename.endsWith(".m3u8")) {
|
|
|
-// contentType = "application/x-mpegURL";
|
|
|
-// } else if (filename.endsWith(".ts")) {
|
|
|
-// contentType = "video/MP2T";
|
|
|
+// // 1. 基础头设置
|
|
|
+// String contentType = getMineType(content, filename);
|
|
|
+//
|
|
|
+// // 2. 设置响应头(根据文件类型)
|
|
|
+//// if (filename.endsWith(".m3u8")) {
|
|
|
+//// contentType = "application/x-mpegURL";
|
|
|
+//// } else if (filename.endsWith(".ts")) {
|
|
|
+//// contentType = "video/MP2T";
|
|
|
+//// }
|
|
|
+// response.setContentType(contentType);
|
|
|
+// response.setContentLength(content.length);
|
|
|
+//
|
|
|
+// // 2. 缓存设置(核心:添加缓存头)
|
|
|
+// // 视频缓存30天,其他文件缓存7天(可按需调整)
|
|
|
+// long maxAge = StrUtil.containsIgnoreCase(contentType, "video") ? 30 * 24 * 60 * 60 : 7 * 24 * 60 * 60;
|
|
|
+// response.setHeader("Cache-Control", "public, max-age=" + maxAge); // 公共缓存,有效期30天
|
|
|
+// response.setHeader("Pragma", "public"); // 兼容老浏览器
|
|
|
+//
|
|
|
+// // 3. 文件名处理(视频用 inline 播放,非视频用 attachment 下载)
|
|
|
+// String disposition = StrUtil.containsIgnoreCase(contentType, "video")
|
|
|
+// ? "inline;filename=" + HttpUtils.encodeUtf8(filename) // 视频:在线播放
|
|
|
+// : "attachment;filename=" + HttpUtils.encodeUtf8(filename); // 其他:下载
|
|
|
+// response.setHeader("Content-Disposition", disposition);
|
|
|
+//
|
|
|
+// // 4. 视频特殊处理(修正原逻辑错误)
|
|
|
+// if (StrUtil.containsIgnoreCase(contentType, "video")) {
|
|
|
+// response.setHeader("Accept-Ranges", "bytes"); // 支持分片
|
|
|
+// // 原代码的 Content-Range 格式错误,已在 getFileContent 中正确设置,此处无需重复
|
|
|
// }
|
|
|
- response.setContentType(contentType);
|
|
|
- response.setContentLength(content.length);
|
|
|
+//
|
|
|
+// // 5. 输出内容
|
|
|
+// IoUtil.write(response.getOutputStream(), false, content);
|
|
|
+
|
|
|
|
|
|
- // 2. 缓存设置(核心:添加缓存头)
|
|
|
- // 视频缓存30天,其他文件缓存7天(可按需调整)
|
|
|
- long maxAge = StrUtil.containsIgnoreCase(contentType, "video") ? 30 * 24 * 60 * 60 : 7 * 24 * 60 * 60;
|
|
|
- response.setHeader("Cache-Control", "public, max-age=" + maxAge); // 公共缓存,有效期30天
|
|
|
- response.setHeader("Pragma", "public"); // 兼容老浏览器
|
|
|
|
|
|
- // 3. 文件名处理(视频用 inline 播放,非视频用 attachment 下载)
|
|
|
- String disposition = StrUtil.containsIgnoreCase(contentType, "video")
|
|
|
- ? "inline;filename=" + HttpUtils.encodeUtf8(filename) // 视频:在线播放
|
|
|
- : "attachment;filename=" + HttpUtils.encodeUtf8(filename); // 其他:下载
|
|
|
- response.setHeader("Content-Disposition", disposition);
|
|
|
|
|
|
- // 4. 视频特殊处理(修正原逻辑错误)
|
|
|
+
|
|
|
+ // 设置 header 和 contentType
|
|
|
+ response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename));
|
|
|
+ String contentType = getMineType(content, filename);
|
|
|
+ response.setContentType(contentType);
|
|
|
+ // 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题
|
|
|
if (StrUtil.containsIgnoreCase(contentType, "video")) {
|
|
|
- response.setHeader("Accept-Ranges", "bytes"); // 支持分片
|
|
|
- // 原代码的 Content-Range 格式错误,已在 getFileContent 中正确设置,此处无需重复
|
|
|
+ response.setHeader("Content-Length", String.valueOf(content.length - 1));
|
|
|
+ response.setHeader("Content-Range", String.valueOf(content.length - 1));
|
|
|
+ response.setHeader("Accept-Ranges", "bytes");
|
|
|
}
|
|
|
-
|
|
|
- // 5. 输出内容
|
|
|
+ // 输出附件
|
|
|
IoUtil.write(response.getOutputStream(), false, content);
|
|
|
}
|
|
|
|