• SpringBoot文件上传下载


    目录

    1、单文件上传

    2、多文件上传

    3、下载、在线查看

    4、上传文件大小限制

    5、自定义上传文件超过限制异常


    1、单文件上传

    这里的enctype的类型是mulitpart/form-data

    两种形式的提交,一种是以form表单的形式,一个是ajax的形式

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>上传文件title>
    6. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">script>
    7. head>
    8. <body>
    9. <form action="/upload" method="post" enctype="multipart/form-data">
    10. <input type="file" name="multipartFile" id="file" value="上传文件">
    11. <input type="button" value="ajax形式上传" id="btn" onclick="onUpload()">
    12. <input type="submit" value="form表单的submit上传">
    13. form>
    14. <script>
    15. //var onUpload = function(){}
    16. function onUpload() {
    17. //$("#multipartFile")[0]表示获取到js对象,files[0]表示获取到上传文件的第一个
    18. var file = $("#file")[0].files[0];
    19. var formData = new FormData(); //这个对象是可以让我们模拟form表单的提交
    20. formData.append("multipartFile", file);
    21. formData.append("isOnline", 1);
    22. $.ajax({
    23. type: "POST",
    24. url: "/upload",
    25. data: formData,
    26. processData: false, //这里设置为false表示不让ajax帮我们把文件转换为对象格式,这里必须设置为false
    27. contentType: false, //这里也要设置为false,不设置可能会出问题
    28. success: function (msg) {
    29. alert("上传文件成功");
    30. }
    31. })
    32. }
    33. script>
    34. body>
    35. html>

    我们将上传的文件放入到resources下面

    这里不能使用request.getServletContext().getRealPath(""),因为这里获取到的路径是tomcat临时文件的目录

    springboot中request.getServletContext().getRealPath(“/”)获取的是一个临时文件夹的地址_猿程序plus的博客-CSDN博客_springboot 获取临时目录

    1. @PostMapping("upload")
    2. @ResponseBody
    3. //将上传的文件放在tomcat目录下面的file文件夹中
    4. public String upload(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) throws IOException {
    5. //获取到原文件全名
    6. String originalFilename = multipartFile.getOriginalFilename();
    7. // request.getServletContext()。getRealPath("")这里不能使用这个,这个是获取servlet的对象,并获取到的一个临时文件的路径,所以这里不能使用这个
    8. //这里获取到我们项目的根目录,classpath下面
    9. String realPath = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
    10. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    11. String format = simpleDateFormat.format(new Date());
    12. //文件夹路径,这里以时间作为目录
    13. String path = realPath + "static/" + format;
    14. //判断文件夹是否存在,存在就不需要重新创建,不存在就创建
    15. File file = new File(path);
    16. if (!file.exists()) {
    17. file.mkdirs();
    18. }
    19. //转换成对应的文件存储,new File第一个参数是目录的路径,第二个参数是文件的完整名字
    20. multipartFile.transferTo(new File(file, originalFilename));
    21. //上传文件的全路径
    22. String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/" + format + "/" + originalFilename;
    23. return url;
    24. }

    2、多文件上传

    多文件上传需要有multiple属性,我们也可以使用accept来利用前端来进行上传文件的指定

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>上传文件title>
    6. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">script>
    7. head>
    8. <body>
    9. <form action="/upload1" method="post" enctype="multipart/form-data">
    10. <input type="file" name="files" multiple value="多文件上传">
    11. <input type="submit" value="多文件上传">
    12. form>
    13. script>
    14. body>
    15. html>

    多文件的上传跟单文件其实差不多,就是对多文件遍历

    1. @PostMapping("upload1")
    2. @ResponseBody
    3. //将上传的文件放在tomcat目录下面的file文件夹中
    4. public String upload1(MultipartFile[] files, HttpServletRequest request, HttpServletResponse response) throws IOException {
    5. List list = new ArrayList<>();
    6. //System.out.println(files.length);
    7. for (MultipartFile multipartFile : files) {
    8. //获取到文件全名
    9. String originalFilename = multipartFile.getOriginalFilename();
    10. // request.getServletContext()。getRealPath("")这里不能使用这个,这个是获取servlet的对象,并获取到的一个临时文件的路径,所以这里不能使用这个
    11. //这里获取到我们项目的根目录,classpath下面
    12. String realPath = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
    13. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    14. String format = simpleDateFormat.format(new Date());
    15. //文件夹路径,这里以时间作为目录
    16. String path = realPath + "static/" + format;
    17. //判断文件夹是否存在,存在就不需要重新创建,不存在就创建
    18. File file = new File(path);
    19. if (!file.exists()) {
    20. file.mkdirs();
    21. }
    22. //转换成对应的文件存储,new File第一个参数是目录的路径,第二个参数是文件的完整名字
    23. multipartFile.transferTo(new File(file, originalFilename));
    24. //上传文件的全路径,一般是放在tomcat中
    25. String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/" + format + "/" + originalFilename;
    26. //System.out.println("url=》》》》》"+url);
    27. list.add(url);
    28. }
    29. return new ObjectMapper().writeValueAsString(list);
    30. }

    3、下载、在线查看

    进行文件下载的时候注意我们最好不要创建一个文件大小的数组来直接读取我们的文件,在文件过大的情况下,可能会导致内存溢出,可以根据实际情况,调整一次读取文件的大小,多次进行读取并输出

    1. @RequestMapping("download")
    2. public void download(HttpServletRequest request, HttpServletResponse response, String name, @RequestParam(defaultValue = "0") int isOnline) throws IOException {
    3. try (ServletOutputStream outputStream = response.getOutputStream();) {
    4. /*
    5. 这里要使用ResourceUtils来获取到我们项目的根目录
    6. 不能使用request.getServletContext().getRealPath("/"),这里获取的是临时文件的根目录(所以不能使用这个)
    7. */
    8. String path = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
    9. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    10. String format = simpleDateFormat.format(new Date());
    11. String realPath = path + "static/" + format + "/" + name;
    12. File file = new File(realPath);
    13. //如果下载的文件不存在
    14. if (!file.exists()) {
    15. response.setContentType("text/html;charset=utf-8");
    16. //response.getWriter().write(str);这种写入的就相当于生成了jsp/html,返回html/jsp,所以需要我们进行contentType的设置
    17. response.getWriter().write("下载的文件不存在");
    18. return;
    19. }
    20. InputStream in = new FileInputStream(realPath);
    21. int read;
    22. //byte[] b = new byte[in.available()];创建一个输入流大小的字节数组,然后把输入流中所有的数据都写入到数组中
    23. byte[] b = new byte[1024];
    24. /*
    25. 1、Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
    26. 2、attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
    27. 3、filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
    28. */
    29. /* 注意:文件名字如果是中文会出现乱码:解决办法:
    30. 1、将name 替换为 new String(filename.getBytes(), "ISO8859-1");
    31. 2、将name 替换为 URLEncoder.encode(filename, "utf-8");
    32. */
    33. if (isOnline == 0) {
    34. //在线打开
    35. response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(name, "utf-8"));
    36. } else {
    37. //下载形式,一般跟application/octet-stream一起使用
    38. response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
    39. //如果单纯写这个也可以进行下载功能,表示以二进制流的形式
    40. response.setContentType("application/octet-stream");
    41. }
    42. //文件大小
    43. response.addHeader("Content-Length", "" + file.length());
    44. while ((read = in.read(b)) > 0) {
    45. outputStream.write(b);
    46. }
    47. } catch (Exception e) {
    48. System.out.println(e.getMessage());
    49. throw e;
    50. }
    51. }

    4、上传文件大小限制

     默认的单文件大小是1m,多文件的总大小10m,超过就会报MaxUploadSizeExceededException异常

    我们根据实际情况进行调整

    例如

    5、自定义上传文件超过限制异常

    springboot自带的异常显示很多时候都不是我们自己想要的,那么对于这种异常,我们可以使用自定义异常来进行显示

    1. package org.springframework.myspringboot.exception;
    2. import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
    3. import org.springframework.web.bind.annotation.ControllerAdvice;
    4. import org.springframework.web.bind.annotation.ExceptionHandler;
    5. import org.springframework.web.bind.annotation.ResponseBody;
    6. import org.springframework.web.multipart.MaxUploadSizeExceededException;
    7. import org.springframework.web.multipart.MultipartFile;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import javax.validation.constraints.Max;
    11. import java.io.IOException;
    12. /**
    13. * @author winnie
    14. * @PackageName:org.springframework.myspringboot.exception
    15. * @Description TODO
    16. * @date 2022/8/3 18:25
    17. */
    18. @ControllerAdvice
    19. public class MyCustomMaxUploadSizeException {
    20. //这里注意如果是参数中有不存在的参数就会导致我们的全局异常失效
    21. @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    22. @ResponseBody
    23. public String MyException(HttpServletRequest request,
    24. HttpServletResponse response,
    25. MaxUploadSizeExceededException e
    26. )throws IOException {
    27. // response.setContentType("text/html;charset=utf-8");
    28. // response.getWriter().write("上传的文件的大小是超过了最大限制");
    29. return "上传的文件的大小是超过了最大限制";
    30. }
    31. }

    这里是一个比较简单的demo,我们也可以返回自定义的错误视图

    例如,引入thymeleaf依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-thymeleafartifactId>
    4. <version>2.2.5.snapshotversion>
    5. dependency>

     

    1. package org.springframework.myspringboot.exception;
    2. import org.springframework.boot.logging.java.SimpleFormatter;
    3. import org.springframework.web.bind.annotation.ControllerAdvice;
    4. import org.springframework.web.bind.annotation.ExceptionHandler;
    5. import org.springframework.web.multipart.MaxUploadSizeExceededException;
    6. import org.springframework.web.servlet.ModelAndView;
    7. import org.springframework.web.servlet.View;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import java.io.IOException;
    11. import java.text.SimpleDateFormat;
    12. import java.util.Date;
    13. /**
    14. * @author winnie
    15. * @PackageName:org.springframework.myspringboot.exception
    16. * @Description TODO
    17. * @date 2022/8/3 18:25
    18. */
    19. @ControllerAdvice
    20. public class MyCustomMaxUploadSizeException {
    21. //这里注意如果是参数中有不存在的参数就会导致我们的全局异常失效
    22. @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    23. public ModelAndView MyException(HttpServletRequest request,
    24. HttpServletResponse response,
    25. MaxUploadSizeExceededException e
    26. )throws IOException {
    27. // response.setContentType("text/html;charset=utf-8");
    28. // response.getWriter().write("上传的文件的大小是超过了最大限制");
    29. ModelAndView modelAndView = new ModelAndView();
    30. modelAndView.addObject("error",e.getMessage());
    31. modelAndView.addObject("date",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
    32. modelAndView.setViewName("uploadException.html");
    33. return modelAndView;
    34. }
    35. }
    1. html>
    2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>上传文件大小超过限制title>
    6. head>
    7. <body>
    8. 上传文件超过大小<br><br>
    9. 发生异常的日期:<p th:text="${date}">p>
    10. 异常信息:<p th:text="${error}">p>
    11. body>
    12. html>

    发生异常的时候

     

  • 相关阅读:
    Ansys Lumerical | 行波 Mach-Zehnder 调制器仿真分析
    前端传String字符串 后端使用enun枚举类出现错误
    机器学习:基于梯度下降算法的线性拟合实现和原理解析
    Linux 开源数据库Mysql-11-mysql集群代理
    【AI领域+餐饮】| 论ChatGPT在餐饮行业的应用展望
    基础复习——共享参数SharedPreferences——记住密码项目——存储卡的文件操作(读写文件&读写图片)...
    mathtype嵌入到wps中
    保研笔记三 数据结构(未完待续)
    排查 docker flow proxy 的 503 问题
    码蹄集 - MT2320 - 跑图:简单图问题
  • 原文地址:https://blog.csdn.net/WinnerBear/article/details/126152716