Spring Boot 2.x 实现文件上传与下载

x33g5p2x  于2021-11-09 转载在 Spring  
字(4.7k)|赞(0)|评价(0)|浏览(773)

前言

文件上传的功能是我们在网页中最为常见的功能,比如网盘文件上传,上传账号图像,Excel文件数据的导入功能等等,都需要通过IO流的方式进行上传和下载文件,本文讲解几种基于SpringBoot 2.x来实现文件上传与下载的操作。

文件上传

配置文件上传大小限制

  1. spring.servlet.multipart.max-file-size=10GB
  2. spring.servlet.multipart.max-request-size=10GB

创建文件上传页面

在resources目录下的templates中创建一个文件上传的页面upload.html,内容如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8" />
  5. <title>文件上传页面</title>
  6. </head>
  7. <body>
  8. <h1>文件上传页面</h1>
  9. <form method="post" action="/fileupload" enctype="multipart/form-data">
  10. 选择要上传的文件:<input type="file" name="file"><br>
  11. <hr>
  12. <input type="submit" value="提交">
  13. </form>
  14. </body>
  15. </html>

页面效果:

创建文件上传Controller

创建文件上传的处理控制器,命名为FileController

  1. /** * 文件上传与下载 */
  2. @Controller
  3. public class FileController {
  4. /** * 文件上传页面 * @return */
  5. @RequestMapping("/upload")
  6. public String file(){
  7. return "upload";
  8. }
  9. /** * 文件上传 * @param file * @return 上传信息 */
  10. @PostMapping("/fileupload")
  11. @ResponseBody
  12. public String fileUpload(@RequestPart MultipartFile file) {
  13. //获取文件原始名称含扩展名
  14. String fileName = file.getOriginalFilename();
  15. //定义文件存放位置
  16. String filePath = "H:\\AAA\\"+fileName;
  17. //将路径放入File实例
  18. File dest = new File(filePath);
  19. //获取文件大小(单位kb) getSize返回字节bit/1024/1024取MB做单位-->1048576=1024x1024
  20. float size = (((float)file.getSize())/1048576);
  21. //获取文件类
  22. String type = file.getContentType();
  23. //判断文件目录是否存在若不存在将进行创建
  24. if (!dest.exists()){
  25. //创建目录
  26. dest.mkdirs();
  27. }
  28. try {
  29. //将接收到的文件传输到给定的目标文件
  30. file.transferTo(dest);
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. //出现异常返回上传失败的信息
  34. return "Upload file success : 上传失败";
  35. }
  36. //上传成功返回文件存放路径
  37. return "Upload file success : 上传成功!文件存放路径为:"+dest.getAbsolutePath()
  38. +"\n文件大小:"+size+"MB"+"\n文件类型:"+type;
  39. }
  40. }

文件上传主要用到的方法及参数:

  • MultipartFile:
    MultipartFile用作参数,用于接收用户上传的文件
  • transferTo()方法
    将接收到的文件传输到给定的目标文件,需要传入带有路径的File实例
  • getOriginalFilename()方法
    获取文件原始名称含扩展名
  • getSize()方法
    获取文件大小,默认单位:KB

演示文件上传效果

文件上传位置在H盘下AAA文件夹中

  1. //定义文件存放位置
  2. String filePath = "H:\\AAA\\"+fileName;

多个文件上传

上传页面

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8" />
  5. <title>文件上传页面</title>
  6. </head>
  7. <body>
  8. <h1>文件上传页面</h1>
  9. <form method="post" action="/fileupload" enctype="multipart/form-data">
  10. 文件1:<input type="file" name="files"><br>
  11. 文件2:<input type="file" name="files"><br>
  12. <hr>
  13. <input type="submit" value="提交">
  14. </form>
  15. </body>
  16. </html>

页面

Controller

  1. /** * 多个文件上传 * @param files * @return 上传信息 */
  2. @PostMapping("/fileupload")
  3. @ResponseBody
  4. public String fileUpload(@RequestPart MultipartFile[] files) {
  5. //遍历文件
  6. for (MultipartFile file : files) {
  7. //获取文件原始名称含扩展名
  8. String fileName = file.getOriginalFilename();
  9. //定义文件存放位置
  10. String filePath = "H:\\AAA\\"+fileName;
  11. //将路径放入File实例
  12. File dest = new File(filePath);
  13. //判断文件目录是否存在若不存在将进行创建
  14. if (!dest.exists()){
  15. //创建目录
  16. dest.mkdirs();
  17. }
  18. try {
  19. //将接收到的文件传输到给定的目标文件
  20. file.transferTo(dest);
  21. } catch (IOException e) {
  22. e.printStackTrace();
  23. //出现异常返回上传失败的信息
  24. return "Upload file success : 上传失败";
  25. }
  26. }
  27. return "Upload file success : 成功上传"+files.length+"个文件";
  28. }

改动说明

  • MultipartFile使用数组,参数名称files对应html页面中input的name,一定要对应。
  • 后续处理文件的主体(for循环内)跟之前的一样,就是对MultipartFile数组通过循环遍历的方式对每个文件进行存储。

演示多个文件上传效果

文件下载

下载

  1. @GetMapping("/download")
  2. public String downloadFile(HttpServletRequest request, HttpServletResponse response) {
  3. String fileName = "wallpaper.jpg";// 文件名
  4. if (fileName != null) {
  5. //设置文件路径
  6. File file = new File("H:\\AAA",fileName);
  7. if (file.exists()) {
  8. // 设置强制下载不打开
  9. response.setContentType("application/force-download");
  10. // 设置文件名
  11. response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
  12. byte[] buffer = new byte[1024];
  13. FileInputStream fis = null;
  14. BufferedInputStream bis = null;
  15. try {
  16. //文件输入流读取本地文件
  17. fis = new FileInputStream(file);
  18. //将文件输入流转成字节缓冲输入流
  19. bis = new BufferedInputStream(fis);
  20. //定义字节输出流
  21. OutputStream os = response.getOutputStream();
  22. //遍历输出字节流
  23. int i = bis.read(buffer);
  24. while (i != -1) {
  25. os.write(buffer, 0, i);
  26. i = bis.read(buffer);
  27. }
  28. return "下载成功";
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. } finally {
  32. //关闭字节缓冲输入流
  33. if (bis != null) {
  34. try {
  35. bis.close();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. //关闭文件输入流
  41. if (fis != null) {
  42. try {
  43. fis.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. }
  49. }
  50. }
  51. return "下载失败";
  52. }

演示效果

H盘中AAA文件夹下有一张图片

@GetMapping("/download")下载接口为:/download

图片正常无损下载

注意点

  • 设置强制下载不打开response.setContentType("application/force-download");
    如果不设置强制下载打开,当你在下载视频、音乐、图片等…浏览器不是第一时间下载,而是在网页直接给你预览出来了。

例如下载图片:

  • 设置文件名response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
    如果不设置文件名,在下载文件的时候会以接口名作为文件名称且没有扩展名。

如图:

更改接口名称为download1

如图

手动添加文件对应类型的扩展名即可正常打开

相关文章