diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java index 00b4687d4..12731edad 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.framework.common.util.servlet; -import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.JakartaServletUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -12,8 +11,6 @@ import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import java.io.IOException; -import java.net.URLEncoder; import java.util.Map; /** @@ -35,21 +32,6 @@ public class ServletUtils { JakartaServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE); } - /** - * 返回附件 - * - * @param response 响应 - * @param filename 文件名 - * @param content 附件内容 - */ - public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException { - // 设置 header 和 contentType - response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - // 输出附件 - IoUtil.write(response.getOutputStream(), false, content); - } - /** * @param request 请求 * @return ua diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java index 2575cc2ef..ed4c34446 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO; @@ -21,13 +20,13 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -36,6 +35,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment; @Tag(name = "管理后台 - 代码生成器") @RestController @@ -145,7 +145,7 @@ public class CodegenController { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipUtil.zip(outputStream, paths, ins); // 输出 - ServletUtils.writeAttachment(response, "codegen.zip", outputStream.toByteArray()); + writeAttachment(response, "codegen.zip", outputStream.toByteArray()); } } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index bbd29dc29..2f92adc0e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.service.file.FileService; @@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment; @Tag(name = "管理后台 - 文件存储") @RestController @@ -88,7 +88,7 @@ public class FileController { response.setStatus(HttpStatus.NOT_FOUND.value()); return; } - ServletUtils.writeAttachment(response, path, content); + writeAttachment(response, path, content); } @GetMapping("/page") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java index ea71f5881..8970c004c 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java @@ -1,9 +1,15 @@ package cn.iocoder.yudao.module.infra.framework.file.core.utils; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.ttl.TransmittableThreadLocal; +import jakarta.servlet.http.HttpServletResponse; import lombok.SneakyThrows; import org.apache.tika.Tika; +import java.io.IOException; +import java.net.URLEncoder; + /** * 文件类型 Utils * @@ -45,4 +51,26 @@ public class FileTypeUtils { return TIKA.get().detect(data, name); } + /** + * 返回附件 + * + * @param response 响应 + * @param filename 文件名 + * @param content 附件内容 + */ + public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException { + // 设置 header 和 contentType + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); + String contentType = getMineType(content, filename); + response.setContentType(contentType); + // 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题 + if (StrUtil.containsIgnoreCase(contentType, "video")) { + response.setHeader("Content-Length", String.valueOf(content.length - 1)); + response.setHeader("Content-Range", String.valueOf(content.length - 1)); + response.setHeader("Accept-Ranges", "bytes"); + } + // 输出附件 + IoUtil.write(response.getOutputStream(), false, content); + } + }