Spring Boot 中文件上传

Spring Boot 中文件上传

  • 一、MultipartFile
  • 二、单文件上传案例
  • 三、多文件上传案例
  • 四、Servlet 规范
  • 五、Servlet 规范实现文件上传


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

一、MultipartFile

  • StandardServletMultipartResolver 内部封装了读取 POST 请求的请求体中的数据,也就是文件内容。我们只需要在 Controller 的方法中加入形参 @ReqestParam(“参数名”) MultipartFile file。MultipartFile 表示上传的文件,其提供了方便的方法保存文件到磁盘。
    public interface MultipartFile extends InputStreamSource {
        String getName();//返回参数的名称
        @Nullable
        String getOriginalFilename();//获取上传文件的名称
        @Nullable
        String getContentType();//返回文件的内容类型
        boolean isEmpty();//判断是否为空,或者上传的文件是否有内容
        long getSize();//返回文件大小 以字节为单位
        byte[] getBytes() throws IOException;//将文件内容转化成一个byte[] 返回
        InputStream getInputStream() throws IOException;//返回InputStream读取文件的内容
        default Resource getResource() {
            return new MultipartFileResource(this);
        }
        //保存上传文件到目标Dest中
        void transferTo(File dest) throws IOException, IllegalStateException;
        default void transferTo(Path dest) throws IOException, IllegalStateException {
            FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
        }
    }
    

二、单文件上传案例

  • 创建两个静态页面,一个用来上传文件(使用表单的方式),另一个用来显示文件上传成功。(注意:静态资源放在 static 目录下,否则访问不到资源
    • 使用表单的方式上传文件必须满足的三个要求:
      • ① enctype=“multipart/form-data”
      • ② method=“post”
      • ③ <input type=“file” value=“选择文件” name=“uploadFile”>
    <!-- 文件名:uploadfile.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传文件</title>
    </head>
    <body>
      <h3>上传文件</h3>
      <div>
    
      </div>
      <form action="uploadFile" enctype="multipart/form-data" method="post">
          选择需要上传的文件:<input type="file" value="选择文件" name="uploadFile"> <br>
          <input type="submit" value="上传文件">
      </form>
    </body>
    </html>
    
    <!-- 文件名:upload_success.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传成功</title>
    </head>
    <body>
      <h3>文件上传成功</h3>
    </body>
    </html>
    
  • 编写controller方法获取请求,然后保存文件。
    @Controller
    public class UploadFileController {
        @PostMapping("/uploadFile")
        public String uploadFile(@RequestParam("uploadFile") MultipartFile multipartFile) throws IOException {
            //首先判断上传的文件是否为空
            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(new File("G:/files/" + dest));//保存文件到指定位置
            }
            //防止刷新,重复上传
            return "redirect:/upload_success.html";
        }
    }
    
  • 编写错误页面
    • 在 SpringBoot 中 /static/error/5xx.html 文件 ===> 如果出现 5xx 的错误自动跳转到整个页面。
    • 在 SpringBoot 中 /static/error/4xx.html 文件 ===> 如果出现 4xx 的错误自动跳转到整个页面 。
    <!-- 文件名:5xx.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>出现了 5XX 错误!!!</h3>
    </body>
    </html>
    
    <!-- 文件名:4xx.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="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 表单上传多文件。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传文件</title>
    </head>
    <body>
      <h3>上传文件</h3>
      <div>
    
      </div>
      <form action="uploadFile" enctype="multipart/form-data" method="post">
          选择需要上传的文件 1:<input type="file" value="选择文件" name="uploadFile"> <br>
          选择需要上传的文件 2:<input type="file" value="选择文件" name="uploadFile"> <br>
          选择需要上传的文件 3:<input type="file" value="选择文件" name="uploadFile"> <br>
          <input type="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 规范的文件上传。

    public interface Part {
        InputStream getInputStream() throws IOException;//获取输入流用于检索文件的内容
        String getContentType();//获取文件内容类型
        String getName();//获取file控件的name属性
        String getSubmittedFileName();//获取上传文件名Servlet3.1 Tomcat8.0实现
        long getSize();//获取上传文件的大小
        void write(String fileName) throws IOException; //将文件内容写入指定的磁盘位置
        void delete() throws IOException;//删除Part数据和临时目录数据,默认会删除
        String getHeader(String name);//获取指定请求头
        Collection<String> getHeaders(String name);//获取指定header名称的集合数据
        Collection<String> getHeaderNames();//获取所有请求头的名称
    }
    

五、Servlet 规范实现文件上传

    @PostMapping("/files")
    public String upload(HttpServletRequest request){
        try {
            for (Part part : request.getParts()) {
                String fileName = extractFileName(part);
                part.write(fileName);
            }
        } catch (IOException | ServletException e) {
            throw new RuntimeException(e);
        }
        return "redirect:/upload_success.html";
    }
    private String extractFileName(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.yal 文件,可配置服务器存储文件位置,例如:
    • spring.servlet.multipart.location=G:/files/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/360340.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录 | ubuntu安装terminal并配置

安装 terminal sudo apt update sudo apt install terminator 重新打开终端就是了 配置&#xff0c;右键 -> 配置文件首选项 快捷键 新建窗口&#xff1a;CtrlShiftT关闭窗口&#xff1a;Ctrl_ShiftW水平划分窗口&#xff1a;CtrlShiftO垂直划分窗口&#xff1a;CtrlShi…

excel中去掉单元格中两个数字之间的空格

excel中去掉单元格中两个数字之间的空格 使用公式&#xff1a;SUBSTITUTE(A1," “,”") 解释&#xff1a;将A1单元格中的空格查找出来并去掉。

【React】在项目中使用阿里图标库

文章目录 打开阿里图标库 》 选择相应图标项目 选择Symbol格式&#xff0c;并复制链接 基于antd新建一个JS文件 MyIcon.js&#xff0c;并绑定上面复制的链接 import { createFromIconfontCN } from ant-design/icons;// 图标有更新时&#xff0c;需更新下面图标链接 export…

【数据结构之二叉树的构建和遍历】

数据结构学习笔记---009 数据结构之二叉树1、二叉树的概念和结构1.1、回顾二叉树的重要性质1.2、回顾二叉树的主要分类1.1、如何实现二叉树&#xff1f; 2、二叉树的实现2.1、二叉树的BinaryTree.h2.2、二叉树的BinaryTree.c2.2.1、二叉树的构建2.2.2、二叉树销毁2.2.3、二叉树…

【Time Series】LSTM代码实战

一、简介 还是那句话&#xff0c;"时间序列金融"是一个很有"钱"景的话题&#xff0c;还是想尝试采用Stock时间序列预测任务DeepLearning。本文提供了LSTM预测股票的源代码。 二、算法原理 长短期记忆网络&#xff08;LSTM&#xff09;是一种特殊的循环神经…

以“美”为鉴,探寻香港比特币现货ETF的未来发展

出品&#xff5c;欧科云链研究院 作者&#xff5c;Hedy Bi 根据The Block于1月29日的报道&#xff0c;嘉实国际成为了首家向香港证监会提交比特币现货ETF申请的机构。早在去年12月22日&#xff0c;香港证监会发布了《有关证监会认可基金投资虚拟资产的通函》&#xff0c;明确…

突破瓶颈,提升开发效率:Spring框架进阶与最佳实践-IOC

IOC相关内容 1.1 bean基础配置1.1.1 bean基础配置(id与class)1.1.2 bean的name属性步骤1&#xff1a;配置别名步骤2:根据名称容器中获取bean对象步骤3:运行程序 1.1.3 bean作用范围scope配置1.1.3.1 验证IOC容器中对象是否为单例验证思路具体实现 1.1.3.2 配置bean为非单例1.1.…

C++文件操作(1)

C文件操作 1.文本的写入及读取文本文件写入文本文件读取 2.二进制文件的写入及读取二进制文件写入二进制文件读取 3.小结 C也有处理文件的能力&#xff0c;其功能实现依赖文件流。文件流是C中用来处理文件输入输出的一种流类。文件流可以用于从文件中读取数据或将数据写入到文件…

开发工具git分支冲突解决

在团队协作的软件开发过程中&#xff0c;Git是一款广泛使用的版本控制系统。然而&#xff0c;当多个开发者同时修改同一文件或代码段时&#xff0c;就会产生分支冲突。解决这些冲突需要仔细的协调和技术知识。本篇博客将介绍Git分支冲突的解决方法&#xff0c;以及开发工具和最…

四工序开料机可以加工什么产品

四工序开料机是木工机械设备中一款重要设备&#xff0c;该设备主要的功能是开料、打孔、拉槽等&#xff0c;一机多用&#xff0c;凭借多功能的加工效果&#xff0c;实现高速加工的效果&#xff0c;那么这样的设备可以加工什么类型的产品呢&#xff1f;大家对此了解多少呢&#…

idea报错 :(java: 找不到符号)

java: 找不到符号 符号: 变量 adminService 位置: 类 com.example.controller.WebController 查到网上一个办法&#xff1a;因为项目是maven&#xff1a;先点clean在点package

anaconda离线安装包的方法

当设备没有网络时&#xff0c;可以使用有网络的设备先下载所需安装包&#xff0c;然后离线拷贝到需要安装的设备&#xff0c;最后安装。 一. 下载所需安装包 下载命令&#xff1a;使用pip download。详细描述参见pip download -h 以"blind-watermark"为例。 pip …

一站式在线协作办公软件ONLYOFFICE,协作更便捷

1、ONLYOFFICE是什么&#xff1f; ONLYOFFICE是一款功能强大的在线协作办公软件&#xff0c;可以创建编辑Word文档、Excel电子表格&#xff0c;PowerPoint&#xff08;PPT&#xff09;演示文稿、Forms表单等多种文件。ONLYOFFICE支持多个平台&#xff0c;无论使用的是 Windows、…

真机调试,微信小程序,uniapp项目在微信开发者工具中真机调试,手机和电脑要连同一个wifi,先清空缓存,页面从登录页进入,再点真机调试,这样就不会报错了

微信小程序如何本地进行真机调试&#xff1f;_unity生成的微信小程序怎么在电脑上真机测试-CSDN博客 微信小程序 真机调试 注意事项 uniapp项目在微信开发者工具中真机调试&#xff0c;手机和电脑要连同一个wifi&#xff0c;先清空缓存&#xff0c;页面从登录页进入&#xf…

怎么保护U盘数据?如何提高U盘的安全性?

U盘作为常用的移动储存设备&#xff0c;能够帮我们存储大量数据。而为了避免数据泄露&#xff0c;我们需要采用专业的方式提高U盘的安全性。那么&#xff0c;怎么保护U盘数据呢&#xff1f;下面我们就一起来了解一下。 如何提高U盘的安全性&#xff1f; 提高U盘数据安全性的方…

3DMAX一键生成样条线纤维插件使用方法

3DMAX一键生成样条线纤维插件使用教程 3DMAX一键生成样条线纤维插件&#xff0c;是一个强大的脚本工具&#xff0c;用于围绕选定的样条线路径创建纤维。它有许多设置用于微调纤维的形状和材质。 【适用版本】 3dMax2010 – 2024&#xff08;不仅限于此范围&#xff09; 【安装…

Rust基础篇之注释、函数

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期专栏回顾 专栏描述…

Wireshark网络协议分析 - UDP协议

在我的博客阅读本文 文章目录 1. 基础2. 实战2.1. 用Go写一个简单的UDP服务器与客户端2.2. Wireshark抓包分析 3. UDP与TCP的区别4. 参考资料 1. 基础 UDP包的数据结构&#xff1a; 2. 实战 2.1. 用Go写一个简单的UDP服务器与客户端 我们这里使用Golang写了一个简单的9830端…

appsmith安装手记:4.Sql server数据库容器安装

appsmith安装好&#xff0c;那就可以看是练练手。 数据当然是来自数据库&#xff0c;那就连接局域网中现成的一台数据库服务器试试&#xff0c;但是连接数据库的时候一直错误。 找到/home/appsmith/backend 目录下的日志&#xff0c;看到了错误&#xff1a; [rootlocalhost bac…

【HarmonyOS应用开发】ArkUI 开发框架-基础篇-第二部分(八)

八、Column&Row组件的使用 概述 一个丰富的页面需要很多组件组成&#xff0c;那么&#xff0c;我们如何才能让这些组件有条不紊地在页面上布局呢&#xff1f;这就需要借助容器组件来实现。 容器组件是一种比较特殊的组件&#xff0c;它可以包含其他的组件&#xff0c;而…