Explorar o código

通过事件发布实现文件异步上传(大文件上传)

linfutong %!s(int64=2) %!d(string=hai) anos
pai
achega
387ac55b45

+ 30 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/controller/SysFileController.java

@@ -60,4 +60,34 @@ public class SysFileController {
             return R.fail(e.getMessage());
         }
     }
+
+    /**
+     * 文件上传(发布事件异步处理)
+     */
+    @PostMapping("/uploadByAsy")
+    public R<SysFile> uploadByAndroid(MultipartFile file) {
+        try {
+            log.info("文件开始上传时间:" + DateUtils.getTime());
+            String fileSuffix = "";
+            String originalFilename = file.getOriginalFilename();
+            if (FileEnum.getPrefix(originalFilename) != null) {
+                fileSuffix = FileEnum.getMessage(originalFilename);
+            }else {
+                fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
+            }
+            List<String> list = Arrays.asList(".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".doc", ".docx", ".ppt", ".pptx", ".mp3", ".mp4", ".avi", ".xls", ".xlsx", ".csv", ".txt", ".apk");
+            if (list.contains(fileSuffix.toLowerCase())) {
+                // 上传并返回访问地址
+                String url = sysFileService.uploadFileByAsyEvent(file);
+                SysFile sysFile = new SysFile();
+                sysFile.setName(FileUtils.getName(url));
+                sysFile.setUrl(url);
+                return R.ok(sysFile);
+            }
+            return R.fail("文件上传类型不正确!");
+        } catch (Exception e) {
+            log.error("上传文件失败", e);
+            return R.fail(e.getMessage());
+        }
+    }
 }

+ 17 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/handle/FileAsyEvent.java

@@ -0,0 +1,17 @@
+package com.zd.base.files.file.handle;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * <p>文件异步信息事件</p>
+ *
+ * @author linft
+ * @version 1.0
+ * @date 2/10/2023
+ */
+public class FileAsyEvent extends ApplicationEvent {
+
+    public FileAsyEvent(Object source) {
+        super(source);
+    }
+}

+ 31 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/handle/FileAsyHandle.java

@@ -0,0 +1,31 @@
+package com.zd.base.files.file.handle;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>事件发布</p>
+ *
+ * @author linft
+ * @version 1.0
+ * @date 2/10/2023
+ */
+@Slf4j
+@Service
+public class FileAsyHandle {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    /**
+     * 发布事件
+     * @param fileInfo
+     */
+    public void publishEvent(PublishFileInfo fileInfo) {
+        // 发布事件
+        applicationContext.publishEvent(new FileAsyEvent(fileInfo));
+        log.info("【发布文件上传事件】 信息内容:"+ fileInfo.toString());
+    }
+}

+ 33 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/handle/FileAsyListener.java

@@ -0,0 +1,33 @@
+package com.zd.base.files.file.handle;
+
+import com.zd.base.files.file.utils.FileUploadUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>事件监听处理</p>
+ *
+ * @author linft
+ * @version 1.0
+ * @date 2/10/2023
+ */
+@Slf4j
+@Component
+public class FileAsyListener {
+
+    @Async
+    @EventListener(FileAsyEvent.class)
+    public void saveSysLog(FileAsyEvent event) {
+        PublishFileInfo fileInfo = (PublishFileInfo) event.getSource();
+        log.info("【监听文件上传事件】 监听到内容:"+ fileInfo.toString());
+        if (fileInfo != null && fileInfo.getFileName() != null) {
+            try {
+                FileUploadUtils.filePublishEventUpload(fileInfo);
+            } catch (Exception e) {
+                log.error("【文件异步事件上传失败】 文件信息:"+fileInfo.getFileName(),"失败原因:"+e);
+            }
+        }
+    }
+}

+ 66 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/handle/PublishFileInfo.java

@@ -0,0 +1,66 @@
+package com.zd.base.files.file.handle;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.Serializable;
+
+/**
+ * <p>发布文件事件信息</p>
+ *
+ * @author linft
+ * @version 1.0
+ * @date 2/10/2023
+ */
+public class PublishFileInfo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String baseDir;
+
+    private String fileName;
+
+    private String filePath;
+
+    private MultipartFile file;
+
+    public String getBaseDir() {
+        return baseDir;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public MultipartFile getFile() {
+        return file;
+    }
+
+    public void setBaseDir(String baseDir) {
+        this.baseDir = baseDir;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public void setFile(MultipartFile file) {
+        this.file = file;
+    }
+
+    @Override
+    public String toString() {
+        return "PublishFileInfo{" +
+                "baseDir='" + baseDir + '\'' +
+                ", fileName='" + fileName + '\'' +
+                ", filePath='" + filePath + '\'' +
+                ", file=" + file +
+                '}';
+    }
+}

+ 5 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/service/FastDfsSysFileServiceImpl.java

@@ -37,4 +37,9 @@ public class FastDfsSysFileServiceImpl implements ISysFileService {
                 FilenameUtils.getExtension(file.getOriginalFilename()), null);
         return domain + "/" + storePath.getFullPath();
     }
+
+    @Override
+    public String uploadFileByAsyEvent(MultipartFile file) throws Exception {
+        return uploadFile(file, Boolean.FALSE);
+    }
 }

+ 9 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/service/ISysFileService.java

@@ -16,4 +16,13 @@ public interface ISysFileService {
      * @throws Exception
      */
     public String uploadFile(MultipartFile file, Boolean ifAsy) throws Exception;
+
+
+    /**
+     * 通过异步事件上传
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    String uploadFileByAsyEvent(MultipartFile file) throws Exception;
 }

+ 13 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/service/LocalSysFileServiceImpl.java

@@ -2,7 +2,10 @@ package com.zd.base.files.file.service;
 
 
 import com.zd.base.files.file.config.ResourcesConfig;
+import com.zd.base.files.file.handle.FileAsyHandle;
+import com.zd.base.files.file.handle.PublishFileInfo;
 import com.zd.base.files.file.utils.FileUploadUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Primary;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
@@ -16,6 +19,8 @@ import org.springframework.web.multipart.MultipartFile;
 @Service
 public class LocalSysFileServiceImpl implements ISysFileService {
 
+    @Autowired
+    private FileAsyHandle fileAsyHandle;
     /**
      * 本地文件上传接口
      *
@@ -36,4 +41,12 @@ public class LocalSysFileServiceImpl implements ISysFileService {
         String url =ResourcesConfig.filePrefix + name;
         return url;
     }
+
+    @Override
+    public String uploadFileByAsyEvent(MultipartFile file) throws Exception {
+        PublishFileInfo fileInfo = FileUploadUtils.generatorFileStoreInfo(ResourcesConfig.filePath, file);
+        //发布事件
+        fileAsyHandle.publishEvent(fileInfo);
+        return ResourcesConfig.filePrefix + fileInfo.getFilePath();
+    }
 }

+ 5 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/file/service/MinioSysFileServiceImpl.java

@@ -41,4 +41,9 @@ public class MinioSysFileServiceImpl implements ISysFileService {
         client.putObject(args);
         return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
     }
+
+    @Override
+    public String uploadFileByAsyEvent(MultipartFile file) throws Exception {
+        return uploadFile(file, Boolean.FALSE);
+    }
 }

+ 34 - 1
zd-modules/zd-base/src/main/java/com/zd/base/files/file/utils/FileUploadUtils.java

@@ -1,6 +1,7 @@
 package com.zd.base.files.file.utils;
 
 import cn.hutool.core.thread.ThreadUtil;
+import com.zd.base.files.file.handle.PublishFileInfo;
 import com.zd.common.core.exception.ServiceException;
 import com.zd.common.core.exception.file.FileNameLengthLimitExceededException;
 import com.zd.common.core.exception.file.FileSizeLimitExceededException;
@@ -98,6 +99,39 @@ public class FileUploadUtils {
         log.info("文件结束上传时间:" + DateUtils.getTime());
         return pathFileName;
     }
+
+    /**
+     * 生成文件存储信息(支持事件发布上传)
+     * @param baseDir
+     * @param file
+     * @return
+     */
+    public static final PublishFileInfo generatorFileStoreInfo(String baseDir, MultipartFile file) {
+        int length = file.getOriginalFilename().length();
+        if (length > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
+            throw new ServiceException("文件名过长,请修改后再次上传");
+        }
+        //assertAllowed(file, allowedExtension);
+        String fileName = extractFilename(file);
+        String path = getPathFileName(fileName);
+        //发布要上传的文件信息
+        PublishFileInfo fileInfo = new PublishFileInfo();
+        fileInfo.setBaseDir(baseDir);
+        fileInfo.setFileName(fileName);
+        fileInfo.setFilePath(path);
+        fileInfo.setFile(file);
+        return fileInfo;
+    }
+
+    /**
+     * 文件上传(支持事件发布上传)
+     * @param fileInfo
+     * @throws IOException
+     */
+    public static final void filePublishEventUpload(PublishFileInfo fileInfo) throws IOException {
+        File desc = getAbsoluteFile(fileInfo.getBaseDir(), fileInfo.getFileName());
+        fileInfo.getFile().transferTo(desc);
+    }
 //
 //    /**
 //     * 文件上传 -不修改文件名
@@ -139,7 +173,6 @@ public class FileUploadUtils {
 
     private static final File getAbsoluteFile(String uploadDir, String fileName){
         File desc = new File(uploadDir + File.separator + fileName);
-
         if (!desc.exists()) {
             if (!desc.getParentFile().exists()) {
                 desc.getParentFile().mkdirs();