Browse Source

feature: add download file API and impl

tubinyan 5 years ago
parent
commit
3290bff674

+ 17 - 0
API Doc.md

@@ -791,6 +791,23 @@ GET course_ware/course/1
          }
      */
      
+2、 下载文件 GET file/download/{originName}
+
+```
+    /**
+     * @api {GET} /file/download/{originName:.+} download
+     * @apiVersion 1.0.0
+     * @apiGroup FileController
+     * @apiName download
+     * @apiParam (请求参数) {String} originName
+     * @apiParam (请求参数) {String} newName
+     * @apiParamExample 请求参数示例
+     * GET /file/download/c6248c34-370f-40b6-91de-b0c3fa540a38.pdf?newName=测试文件.pdf
+     * @apiSuccess (响应结果) {Object} response
+     * @apiSuccessExample 响应结果示例
+     * null
+     */
+```     
      
 ### CourseOrder
 

+ 7 - 4
src/main/java/cn/seecoder/courselearning/controller/FileController.java

@@ -3,13 +3,11 @@ package cn.seecoder.courselearning.controller;
 import cn.seecoder.courselearning.service.FileService;
 import cn.seecoder.courselearning.vo.FileInfoVO;
 import cn.seecoder.courselearning.vo.ResultVO;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
 
 @RestController
 @RequestMapping("/file")
@@ -21,4 +19,9 @@ public class FileController {
     public ResultVO<FileInfoVO> upload(@RequestParam("file") MultipartFile file) {
         return fileService.uploadFile(file);
     }
+
+    @GetMapping("/download/{originName:.+}")
+    public void download(@PathVariable String originName, @RequestParam String newName, HttpServletResponse response) {
+        fileService.downloadFile(originName, newName, response);
+    }
 }

+ 3 - 0
src/main/java/cn/seecoder/courselearning/service/FileService.java

@@ -4,6 +4,9 @@ import cn.seecoder.courselearning.vo.FileInfoVO;
 import cn.seecoder.courselearning.vo.ResultVO;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
+
 public interface FileService {
     ResultVO<FileInfoVO> uploadFile(MultipartFile file);
+    void downloadFile(String originName, String newName, HttpServletResponse response);
 }

+ 44 - 0
src/main/java/cn/seecoder/courselearning/serviceimpl/FileServiceImpl.java

@@ -9,10 +9,15 @@ import cn.seecoder.courselearning.vo.ResultVO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 
 @Service
 public class FileServiceImpl implements FileService {
@@ -33,4 +38,43 @@ public class FileServiceImpl implements FileService {
         }
         return new ResultVO<>(-1, "服务器错误,请联系网站管理员。");
     }
+
+    @Override
+    public void downloadFile(String originName, String newName, HttpServletResponse response) {
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        response.setContentType("application/x-msdownload");
+        try {
+            Resource resource = FileHelper.loadFileAsResource(path, originName);
+            if(resource == null)
+                return;
+            inputStream = resource.getInputStream();
+            //1.设置文件ContentType类型
+            response.setContentType("application/octet-stream;charset=UTF-8");
+            outputStream = response.getOutputStream();
+            //2.转码  UTF_8为传入的newName编码的格式 ISO_8859_1为浏览器默认编码
+            String convertName = new String(newName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
+            //3.设置 header  Content-Disposition
+            response.setHeader("Content-Disposition", "attachment; filename=" + convertName);
+            int b = 0;
+            byte[] buffer = new byte[2048];
+            while (b != -1) {
+                b = inputStream.read(buffer);
+                if (b != -1) {
+                    outputStream.write(buffer, 0, b);
+                }
+            }
+        } catch (IOException | MyException e) {
+            logger.error("文件下载时出错", e);
+        } finally {
+            try {
+                if(inputStream != null)
+                    inputStream.close();
+                if (outputStream != null)
+                    outputStream.close();
+            } catch (IOException e) {
+                logger.error("输入流或输出流关闭时出错!", e);
+            }
+        }
+    }
 }

+ 24 - 1
src/main/java/cn/seecoder/courselearning/util/FileHelper.java

@@ -3,6 +3,8 @@ import cn.seecoder.courselearning.enums.ExceptionType;
 import cn.seecoder.courselearning.exception.MyException;
 import cn.seecoder.courselearning.vo.FileInfoVO;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
 import org.springframework.util.FileCopyUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
@@ -10,13 +12,16 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.UUID;
 
 @Slf4j
 public class FileHelper {
     /**
      * 保存文件
-     * @param directoryPath 目录路径
+     * @param directoryPath 目录路径(以 / 结尾)
      * @param file 文件
      * @return 保存成功后的文件名
      */
@@ -45,6 +50,24 @@ public class FileHelper {
         return new FileInfoVO(newName, type, size);
     }
 
+    /**
+     * 加载文件为资源
+     * @param directoryPath 目录路径(以 / 结尾)
+     * @param fileName 文件名
+     * @return 输入流资源
+     */
+    public static Resource loadFileAsResource(String directoryPath, String fileName) {
+        try {
+            Path filePath = Paths.get(directoryPath+fileName);
+            Resource resource = new UrlResource(filePath.toUri());
+            if(resource.exists())
+                return resource;
+        } catch (MalformedURLException ex) {
+            throw MyException.of(ExceptionType.SERVER_ERROR, "服务端错误,加载文件资源时出错!");
+        }
+        return null;
+    }
+
     public static boolean delete(String directoryPath, String fileName){
         if(StringUtils.hasText(fileName)){
             File file = new File(directoryPath + fileName);