Commit 7f0485e872ca78e6b98e8bbfa1a9af39da475611

Authored by YunaiV
1 parent fd832e23

【修复】解决视频地址在移动端播放的兼容性问题

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
1 package cn.iocoder.yudao.framework.common.util.servlet; 1 package cn.iocoder.yudao.framework.common.util.servlet;
2 2
3 -import cn.hutool.core.io.IoUtil;  
4 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
5 import cn.hutool.extra.servlet.JakartaServletUtil; 4 import cn.hutool.extra.servlet.JakartaServletUtil;
6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -12,8 +11,6 @@ import org.springframework.web.context.request.RequestAttributes; @@ -12,8 +11,6 @@ import org.springframework.web.context.request.RequestAttributes;
12 import org.springframework.web.context.request.RequestContextHolder; 11 import org.springframework.web.context.request.RequestContextHolder;
13 import org.springframework.web.context.request.ServletRequestAttributes; 12 import org.springframework.web.context.request.ServletRequestAttributes;
14 13
15 -import java.io.IOException;  
16 -import java.net.URLEncoder;  
17 import java.util.Map; 14 import java.util.Map;
18 15
19 /** 16 /**
@@ -36,21 +33,6 @@ public class ServletUtils { @@ -36,21 +33,6 @@ public class ServletUtils {
36 } 33 }
37 34
38 /** 35 /**
39 - * 返回附件  
40 - *  
41 - * @param response 响应  
42 - * @param filename 文件名  
43 - * @param content 附件内容  
44 - */  
45 - public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {  
46 - // 设置 header 和 contentType  
47 - response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));  
48 - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);  
49 - // 输出附件  
50 - IoUtil.write(response.getOutputStream(), false, content);  
51 - }  
52 -  
53 - /**  
54 * @param request 请求 36 * @param request 请求
55 * @return ua 37 * @return ua
56 */ 38 */
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java
@@ -5,7 +5,6 @@ import cn.hutool.core.util.ZipUtil; @@ -5,7 +5,6 @@ import cn.hutool.core.util.ZipUtil;
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;  
9 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO; 8 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
10 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO; 9 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO;
11 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO; 10 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO;
@@ -17,17 +16,17 @@ import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; @@ -17,17 +16,17 @@ import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
17 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 16 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
18 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; 17 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
19 import cn.iocoder.yudao.module.infra.service.codegen.CodegenService; 18 import cn.iocoder.yudao.module.infra.service.codegen.CodegenService;
20 -import io.swagger.v3.oas.annotations.tags.Tag; 19 +import io.swagger.v3.oas.annotations.Operation;
21 import io.swagger.v3.oas.annotations.Parameter; 20 import io.swagger.v3.oas.annotations.Parameter;
22 import io.swagger.v3.oas.annotations.Parameters; 21 import io.swagger.v3.oas.annotations.Parameters;
23 -import io.swagger.v3.oas.annotations.Operation; 22 +import io.swagger.v3.oas.annotations.tags.Tag;
  23 +import jakarta.annotation.Resource;
  24 +import jakarta.servlet.http.HttpServletResponse;
  25 +import jakarta.validation.Valid;
24 import org.springframework.security.access.prepost.PreAuthorize; 26 import org.springframework.security.access.prepost.PreAuthorize;
25 import org.springframework.validation.annotation.Validated; 27 import org.springframework.validation.annotation.Validated;
26 import org.springframework.web.bind.annotation.*; 28 import org.springframework.web.bind.annotation.*;
27 29
28 -import jakarta.annotation.Resource;  
29 -import jakarta.servlet.http.HttpServletResponse;  
30 -import jakarta.validation.Valid;  
31 import java.io.ByteArrayInputStream; 30 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream; 31 import java.io.ByteArrayOutputStream;
33 import java.io.IOException; 32 import java.io.IOException;
@@ -36,6 +35,7 @@ import java.util.Map; @@ -36,6 +35,7 @@ import java.util.Map;
36 35
37 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
38 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 37 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  38 +import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
39 39
40 @Tag(name = "管理后台 - 代码生成器") 40 @Tag(name = "管理后台 - 代码生成器")
41 @RestController 41 @RestController
@@ -145,7 +145,7 @@ public class CodegenController { @@ -145,7 +145,7 @@ public class CodegenController {
145 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 145 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
146 ZipUtil.zip(outputStream, paths, ins); 146 ZipUtil.zip(outputStream, paths, ins);
147 // 输出 147 // 输出
148 - ServletUtils.writeAttachment(response, "codegen.zip", outputStream.toByteArray()); 148 + writeAttachment(response, "codegen.zip", outputStream.toByteArray());
149 } 149 }
150 150
151 } 151 }
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
@@ -6,7 +6,6 @@ import cn.hutool.core.util.URLUtil; @@ -6,7 +6,6 @@ import cn.hutool.core.util.URLUtil;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;  
10 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*; 9 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
11 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; 10 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
12 import cn.iocoder.yudao.module.infra.service.file.FileService; 11 import cn.iocoder.yudao.module.infra.service.file.FileService;
@@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.*; @@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.*;
26 import org.springframework.web.multipart.MultipartFile; 25 import org.springframework.web.multipart.MultipartFile;
27 26
28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
29 29
30 @Tag(name = "管理后台 - 文件存储") 30 @Tag(name = "管理后台 - 文件存储")
31 @RestController 31 @RestController
@@ -88,7 +88,7 @@ public class FileController { @@ -88,7 +88,7 @@ public class FileController {
88 response.setStatus(HttpStatus.NOT_FOUND.value()); 88 response.setStatus(HttpStatus.NOT_FOUND.value());
89 return; 89 return;
90 } 90 }
91 - ServletUtils.writeAttachment(response, path, content); 91 + writeAttachment(response, path, content);
92 } 92 }
93 93
94 @GetMapping("/page") 94 @GetMapping("/page")
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java
1 package cn.iocoder.yudao.module.infra.framework.file.core.utils; 1 package cn.iocoder.yudao.module.infra.framework.file.core.utils;
2 2
  3 +import cn.hutool.core.io.IoUtil;
  4 +import cn.hutool.core.util.StrUtil;
3 import com.alibaba.ttl.TransmittableThreadLocal; 5 import com.alibaba.ttl.TransmittableThreadLocal;
  6 +import jakarta.servlet.http.HttpServletResponse;
4 import lombok.SneakyThrows; 7 import lombok.SneakyThrows;
5 import org.apache.tika.Tika; 8 import org.apache.tika.Tika;
6 9
  10 +import java.io.IOException;
  11 +import java.net.URLEncoder;
  12 +
7 /** 13 /**
8 * 文件类型 Utils 14 * 文件类型 Utils
9 * 15 *
@@ -45,4 +51,26 @@ public class FileTypeUtils { @@ -45,4 +51,26 @@ public class FileTypeUtils {
45 return TIKA.get().detect(data, name); 51 return TIKA.get().detect(data, name);
46 } 52 }
47 53
  54 + /**
  55 + * 返回附件
  56 + *
  57 + * @param response 响应
  58 + * @param filename 文件名
  59 + * @param content 附件内容
  60 + */
  61 + public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
  62 + // 设置 header 和 contentType
  63 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
  64 + String contentType = getMineType(content, filename);
  65 + response.setContentType(contentType);
  66 + // 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题
  67 + if (StrUtil.containsIgnoreCase(contentType, "video")) {
  68 + response.setHeader("Content-Length", String.valueOf(content.length - 1));
  69 + response.setHeader("Content-Range", String.valueOf(content.length - 1));
  70 + response.setHeader("Accept-Ranges", "bytes");
  71 + }
  72 + // 输出附件
  73 + IoUtil.write(response.getOutputStream(), false, content);
  74 + }
  75 +
48 } 76 }