0


Spring Boot 中文件上传

Spring Boot 中文件上传


  • 上传文件大家用的最多的就是 Apache Commons FileUpload,这个库使用非常广泛。Spring Boot3 版本中已经不能使用了。代替它的是 Spring Boot 中自己实现的文件上传。
  • Spring Boot 上传文件现在变得非常简单。提供了封装好的处理上传文件的接口 MultipartReslover,用于解析上传文件的请求,它的内部实现类 StandardServletMultipartResolver。之前常用的 CommonsMultipartResolver 不能使用了。 CommonsMultipartResolver 是使用 Apache Commons File Upload 库时的处理类。

一、MultipartFile

  • StandardServletMultipartResolver 内部封装了读取 POST 请求的请求体中的数据,也就是文件内容。我们只需要在 Controller 的方法中加入形参 @ReqestParam("参数名") MultipartFile fileMultipartFile 表示上传的文件,其提供了方便的方法保存文件到磁盘。MultipartFile API 如下:publicinterfaceMultipartFileextendsInputStreamSource{StringgetName();//返回参数的名称@NullableStringgetOriginalFilename();//获取上传文件的名称@NullableStringgetContentType();//返回文件的内容类型booleanisEmpty();//判断是否为空,或者上传的文件是否有内容longgetSize();//返回文件大小 以字节为单位byte[]getBytes()throwsIOException;//将文件内容转化成一个byte[] 返回InputStreamgetInputStream()throwsIOException;//返回InputStream读取文件的内容defaultResourcegetResource(){returnnewMultipartFileResource(this);}//保存上传文件到目标Dest中voidtransferTo(File dest)throwsIOException,IllegalStateException;defaultvoidtransferTo(Path dest)throwsIOException,IllegalStateException{FileCopyUtils.copy(this.getInputStream(),Files.newOutputStream(dest));}}

二、单文件上传案例

  • 创建两个静态页面,一个用来上传文件(使用表单的方式),另一个用来显示文件上传成功。(注意:静态资源放在 static 目录下,否则访问不到资源) - 使用表单的方式上传文件必须满足的三个要求: - ① enctype=“multipart/form-data”- ② method=“post”- ③ <input type=“file” value=“选择文件” name=“uploadFile”><!-- 文件名:uploadfile.html --><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>上传文件</title></head><body><h3>上传文件</h3><div></div><formaction="uploadFile"enctype="multipart/form-data"method="post"> 选择需要上传的文件:<inputtype="file"value="选择文件"name="uploadFile"><br><inputtype="submit"value="上传文件"></form></body></html>``````<!-- 文件名:upload_success.html --><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>文件上传成功</title></head><body><h3>文件上传成功</h3></body></html>
  • 编写controller方法获取请求,然后保存文件。@ControllerpublicclassUploadFileController{@PostMapping("/uploadFile")publicStringuploadFile(@RequestParam("uploadFile")MultipartFile multipartFile)throwsIOException{//首先判断上传的文件是否为空if(!multipartFile.isEmpty()){String suffix =".unknown";//初始文件后缀为不知道String name = multipartFile.getOriginalFilename();//获取上传的文件名System.out.println(name);//获取文件的后缀if(name !=null&& name.indexOf(".")>0){ suffix = name.substring(name.indexOf("."));}String dest =UUID.randomUUID()+ suffix;//生成保存的文件名 multipartFile.transferTo(newFile("G:/files/"+ dest));//保存文件到指定位置}//防止刷新,重复上传return"redirect:/upload_success.html";}}
  • 编写错误页面 - 在 SpringBoot 中 /static/error/5xx.html 文件 ===> 如果出现 5xx 的错误自动跳转到整个页面。- 在 SpringBoot 中 /static/error/4xx.html 文件 ===> 如果出现 4xx 的错误自动跳转到整个页面 。<!-- 文件名:5xx.html --><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><h3>出现了 5XX 错误!!!</h3></body></html>``````<!-- 文件名:4xx.html --><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><h3>出现了 4XX 错误!!!</h3></body></html>
  • 设置上传文件的大小 - Spring Boot 默认单个文件最大支持1M,一次请求最大10M。改变默认值,需要修改 application.yml 配置文件。file-size-threshold 超过指定大小,直接写文件到磁盘,不在内存处理。在这里插入图片描述
  • 不能只考虑SpingBoot每次请求的文件最大大小,还需要设置服务器每次请求的大小。

三、多文件上传案例

  • 多文件上传,在接收文件参数部分有所改变 MultipartFile[] files。循环遍历数组解析每一个上传的文件。
  • 前端通过 form 表单上传多文件。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>上传文件</title></head><body><h3>上传文件</h3><div></div><formaction="uploadFile"enctype="multipart/form-data"method="post"> 选择需要上传的文件 1:<inputtype="file"value="选择文件"name="uploadFile"><br> 选择需要上传的文件 2:<inputtype="file"value="选择文件"name="uploadFile"><br> 选择需要上传的文件 3:<inputtype="file"value="选择文件"name="uploadFile"><br><inputtype="submit"value="上传文件"></form></body></html>

四、Servlet 规范

  • Servlet3.0 规范中,定义了 Jakarta.servlet.http.Part 接口处理 mulitipart/form-data``````POST 请求中接收到的表单数据。有了 Part 对象,其 write() 方法将上传文件保存到服务器本地的磁盘中。
  • HttpServletRequest 接口中引入的新方法:- getParts():返回 Part 对象的集合。- getPart(字符串名称):检索具有给定名称的单个 Part 对象。
  • Spring Boot3 使用的 Servlet 规范是基于 5 的,所以上传文件使用的就是 Part 接口。
  • StandardServletMultipartResolver 对 Part 接口进行的封装,实现基于 Servlet 规范的文件上传。publicinterfacePart{InputStreamgetInputStream()throwsIOException;//获取输入流用于检索文件的内容StringgetContentType();//获取文件内容类型StringgetName();//获取file控件的name属性StringgetSubmittedFileName();//获取上传文件名Servlet3.1 Tomcat8.0实现longgetSize();//获取上传文件的大小voidwrite(String fileName)throwsIOException;//将文件内容写入指定的磁盘位置voiddelete()throwsIOException;//删除Part数据和临时目录数据,默认会删除StringgetHeader(String name);//获取指定请求头Collection<String>getHeaders(String name);//获取指定header名称的集合数据Collection<String>getHeaderNames();//获取所有请求头的名称}

五、Servlet 规范实现文件上传

@PostMapping("/files")publicStringupload(HttpServletRequest request){try{for(Part part : request.getParts()){String fileName =extractFileName(part);
                part.write(fileName);}}catch(IOException|ServletException e){thrownewRuntimeException(e);}return"redirect:/upload_success.html";}privateStringextractFileName(Part part){String contentDis = part.getHeader("content-disposition");String[] items = contentDis.split(";");for(String s : items){if(s.trim().startsWith("filename")){return s.substring(s.indexOf("=")+2, s.length()-1);}}return"";}
  • 上传文件包含 header 头 content-disposition,类似如下的内容,可获取文件原始名称。 - form-data; name=“dataFile”;filename=“header.png”
  • application.yml 文件,可配置服务器存储文件位置,例如: - spring.servlet.multipart.location=G:/files/

标签: spring boot 后端

本文转载自: https://blog.csdn.net/weixin_65032328/article/details/135936793
版权归原作者 小宝945 所有, 如有侵权,请联系我们删除。

“Spring Boot 中文件上传”的评论:

还没有评论