Commit 7f0485e872ca78e6b98e8bbfa1a9af39da475611
1 parent
fd832e23
【修复】解决视频地址在移动端播放的兼容性问题
Showing
4 changed files
with
37 additions
and
27 deletions
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 | } |