随笔(一)『SpringBoot上传、下载』

package com.baihua.controller;

import com.baihua.common.Constants;
import com.baihua.common.Result;
import com.baihua.exception.MyException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@RestController
@RequestMapping("file")
@Slf4j
public class FileController {

    // 上传路径
    private String uploadPath = "E:\\Jack_he\\upload\\files\\";

    // 下载基本路径
    private String downloadPath = "http://localhost:8086/file/download?fileName=";

    /**
     * 上传
     */
    @PostMapping("upload")
    public Result upload(@RequestParam("file") MultipartFile multipartFile) {
        if (multipartFile.isEmpty()) {
            throw new MyException(Constants.CODE_10400, "文件为空,请重新上传");
        }

        String originalFilename = multipartFile.getOriginalFilename(); // 原始文件名
        File file = new File(uploadPath + originalFilename); // 需要上传到哪里
        if (!file.exists()) { // 文件不存在则创建
            file.mkdirs();
        }

        try {
            multipartFile.transferTo(file); // 上传的文件写到具体的位置
        } catch (IOException e) {
            log.error("上传失败:{}", e);
            throw new MyException(Constants.CODE_10400, "文件上传失败");
        }

        // TODO 保存到DB

        Result result = new Result();
        result.setCode(Constants.CODE_0);
        result.setMsg("success");
        result.setData(downloadPath + originalFilename);
        return result;
    }


    /**
     * 下载
     */
    @GetMapping("download")
    public void download(HttpServletResponse resp, @RequestParam String fileName) throws IOException {
        if (StringUtils.isEmpty(fileName)) {
            throw new MyException(Constants.CODE_10300, "参数错误");
        }

        String readPath = uploadPath + fileName; // 下载哪里的文件
        FileInputStream is = new FileInputStream(readPath); // 创建输入流
        BufferedInputStream bis = new BufferedInputStream(is); // 创建带缓存的输入流
        byte[] bytes = new byte[8 * 1024]; // 8kb的字节数组,每次最多读取8kb数据
        int len = 0;

        OutputStream os = resp.getOutputStream();
        resp.setContentType("application/octet-stream"); // 媒体格式类型:二进制流数据
        try {
            String encode = URLEncoder.encode(fileName, "UTF-8"); // 解决中文乱码
            resp.setHeader("Content-Disposition", "attachment;fileName=" + encode); // Content-Disposition:如何处理响应内容,attchment:以附件形式下载
            while ((len = bis.read(bytes)) != -1) { // 读取到数据就写出去
                os.write(bytes, 0, len);
            }
        } catch (UnsupportedEncodingException e) {
            log.error("解决中文乱码异常:{}", e);
            throw new MyException(Constants.CODE_10400, "解决中文乱码异常");
        } catch (IOException e) {
            log.error("I/O流写出时发生异常:{}", e);
            throw new MyException(Constants.CODE_10400, "I/O流写出时发生异常");
        }finally {
            // 关闭相应I/O连接
            if (is != null) {
                is.close();
            }
            if (bis != null) {
                bis.close();
            }
            if (os != null) {
                os.close();
            }
        }

    }

}
posted @   小昕昕  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示