【Spring MVC】小文件上传的多种方法

文章目录

  • 方法参数
  • 单文件上传
    • 1. MultipartFile 的 transferTo(File dest)
    • 2. MultipartFile 的 transferTo(Path dest)
    • 3. MultipartFile + Files.write(Path path, byte[] bytes, OpenOption... options)
    • 4. MultipartFile + Files.copy(InputStream in, Path target, CopyOption... options)
    • 5. HttpServletRequest 的 getPart(String var1)
  • 多文件上传(兼容单文件)
    • 1. MultipartFile[ ] + 前四种上传方法
    • 2. List<MultipartFile> + 前四种上传方法
    • 3. MultipartHttpServletRequest + 前四种上传方法
    • 4. HttpServletRequest 的 getParts()
  • 补充
  • 总结

Win、JDK 17、 Spring Boot 3.1.2

方法参数

  1. Spring 的 MultipartFile(最常用)
  2. Spring 的 MultipartHttpServletRequest
  3. Servlet 的 HttpServletRequest(原生)

单文件上传

1. MultipartFile 的 transferTo(File dest)

@PostMapping("/upload-1")
public String upload1(@RequestPart("file") MultipartFile mf) throws IOException {String filename = mf.getOriginalFilename();mf.transferTo(new File("d:/", filename));return "upload success";
}

2. MultipartFile 的 transferTo(Path dest)

@PostMapping("/upload-2")
public String upload2(@RequestParam("file") MultipartFile mf) throws IOException {String filename = mf.getOriginalFilename();Path path = Paths.get("upload", filename);mf.transferTo(path);return "upload success";
}

3. MultipartFile + Files.write(Path path, byte[] bytes, OpenOption… options)

@PostMapping("/upload-3")
public String upload3(@RequestParam("file") MultipartFile mf) throws IOException {String filename = mf.getOriginalFilename();Path path = Paths.get("upload", filename);Files.write(path, mf.getBytes());return "upload success";
}

4. MultipartFile + Files.copy(InputStream in, Path target, CopyOption… options)

@PostMapping("/upload-4")
public String upload4(@RequestParam("file") MultipartFile mf) throws IOException {String filename = mf.getOriginalFilename();Path path = Paths.get("upload", filename);// 若文件已存在,则会抛出 FileAlreadyExistsExceptionFiles.copy(mf.getInputStream(), path);return "upload success";
}

5. HttpServletRequest 的 getPart(String var1)

public String upload8(HttpServletRequest req) throws ServletException, IOException {// 获取上传的文件流,单文件Part filePart = req.getPart("file");String filename = filePart.getSubmittedFileName();// 构建目标文件对象Path path = Paths.get("upload", filename);byte[] bytes = filePart.getInputStream().readAllBytes();InputStream in = filePart.getInputStream();// Files.write(path, bytes);// Files.copy(in,path);return "upload success";
}

多文件上传(兼容单文件)

1. MultipartFile[ ] + 前四种上传方法

@PostMapping("/upload-5")
public String upload5(@RequestParam("files") MultipartFile[] files) {for (MultipartFile mf : files) {// 同理又有四种// mf.transferTo(File dest)// mf.transferTo(Path dest)// Files.write(Path path, byte[] bytes, OpenOption... options)// Files.copy(mf.getInputStream(), path);}return "upload success";
}

2. List<MultipartFile> + 前四种上传方法

@PostMapping("/upload-6")
public String upload6(@RequestParam("files") List<MultipartFile> files) {for (MultipartFile mf : files) {// 同理又有四种// mf.transferTo(File dest)// mf.transferTo(Path dest)// Files.write(Path path, byte[] bytes, OpenOption... options)// Files.copy(mf.getInputStream(), path);}return "upload success";
}

3. MultipartHttpServletRequest + 前四种上传方法

@PostMapping("/upload-7")
public String upload7(MultipartHttpServletRequest req) {req.getFileNames().forEachRemaining(name -> {for (MultipartFile mf : req.getFiles(name)) {// 同理又有四种// mf.transferTo(File dest)// mf.transferTo(Path dest)// Files.write(Path path, byte[] bytes, OpenOption... options)// Files.copy(mf.getInputStream(), path);}});return "upload success";
}

4. HttpServletRequest 的 getParts()

@PostMapping("/upload-9")
public String upload9(HttpServletRequest req) throws ServletException, IOException {Collection<Part> parts = req.getParts();for (Part part : parts) {String filename = part.getSubmittedFileName();Path path = Paths.get("upload", filename);byte[] bytes = part.getInputStream().readAllBytes();InputStream in = part.getInputStream();// Files.write(path, bytes);// Files.copy(in,path);}return "upload success";
}

补充

以上方法仅为示例代码,注意 NPE
以上方法仅适用于小文件上传,不适合上百 MB 的大文件上传
Files.copy() 无法覆盖文件,会抛异常
@RequestPart 可替代 @RequestParam

@RequestParam@RequestPart 都是Spring框架中用于处理HTTP请求参数的注解,但它们在处理文件上传时有一些区别。

  1. @RequestParam:

    • 用于处理普通的表单字段和查询参数,适用于处理常规的请求参数。
    • 在处理文件上传时,可以用于接收文件的元数据(如文件名、大小等),但无法直接获取文件的内容。
    • 对于文件上传,@RequestParam 需要配合 MultipartFile 类型参数来获取文件的内容。

    示例:

    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {// 处理文件上传逻辑// ...
    }
    
  2. @RequestPart:

    • 用于处理文件上传请求,特别适用于处理发送 multipart/form-data 类型的请求。
    • 允许直接获取文件的内容,不需要再额外使用 MultipartFile 类型参数来获取文件内容。
    • 可以用于接收文件的元数据(如文件名、大小等),也可以直接获取文件的字节流。

    示例:

    @PostMapping("/upload")
    public String handleFileUpload(@RequestPart("file") byte[] fileBytes,@RequestPart("file") InputStream fileInputStream,@RequestPart("file") Part filePart) {// 处理文件上传逻辑// ...
    }
    

综上所述,@RequestParam 用于处理常规的请求参数和文件元数据,需要额外使用 MultipartFile 类型参数来获取文件内容。而 @RequestPart 则更适用于处理文件上传请求,允许直接获取文件的内容,并且可以用于接收文件元数据。

在实际使用中,你可以根据请求的具体内容和需求来选择合适的注解,以及结合相应的处理方式。如果仅处理文件上传,使用 @RequestPart 更为直接方便;如果需要处理普通请求参数和文件上传一起,可以使用 @RequestParam 来处理。

总结

Spring MVC 提供了多种方法来处理文件上传,开发者可以根据项目需求和性能考虑选择适合的方法。对于小文件上传,使用 MultipartFile 接口是简单有效的选择。

无论选择哪种方法,都应该注意文件上传过程中的安全性和性能,避免潜在的漏洞和性能问题。合理设置文件大小限制,处理异常情况,以及对文件上传进行必要的验证和授权,都是保障文件上传功能正常运作的重要因素。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20 QTreeWidget控件

代码&#xff1a; //treeWidget树控件//1&#xff1a;设置头部标签 QStringList()匿名对象创建ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");//2&#xff1a;设置itemQTreeWidgetItem * liItem new QTreeWidg…

Kubernetes(K8s)从入门到精通系列之二:入门案例启动MySQL服务和Tomcat应用

Kubernetes K8s 从入门到精通系列之二:入门案例启动MySQL服务和Tomcat应用 一、实际应用案例二、部署K8s集群三、创建Mysql的Deployment,启动MySQL服务四、创建MySQL的Service五、创建tomcat的Deployment,启动Tomcat应用六、通过浏览器访问网页一、实际应用案例 运行在Tomca…

MySQL IF()函数:在查询中灵活应用条件逻辑

前言&#xff1a; 在数据库查询中&#xff0c;我们经常需要根据条件逻辑来选择返回不同的结果。MySQL提供了强大的IF()函数&#xff0c;使得在查询语句中应用条件逻辑变得非常简单和灵活。本篇文章将深入探讨MySQL的IF()函数&#xff0c;并展示如何在查询中利用它来进行条件判断…

Linux 系统中异常与中断

文章目录 异常与中断的关系中断的处理流程异常向量表Linux 系统对中断的处理ARM 处理器程序运行的过程程序被中断时&#xff0c;怎么保存现场Linux 系统对中断处理的演进Linux 对中断的扩展&#xff1a;硬件中断、软件中断硬件中断软件中断 中断处理原则&#xff1a;耗时中断的…

【面试题】万字总结MYSQL面试题

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 1、三大范式 2、DML 语句和 DDL 语句区别 3、主键和外键的区别 4、drop、delete、truncate 区别 5、基础架构 6、MyISAM 和 InnoDB 有什么区别&#xff1f; 7、推荐自增id作为…

Jvm 之 Stop The World 机制

文章目录 一、STW简介二、为什么需要STW三、STW机制触发实际1. 垃圾回收&#xff08;GC&#xff09;&#xff1a;2. 类加载和卸载&#xff1a;3. JIT编译&#xff1a; 四、STW带来的问题1. 停顿时间延长&#xff1a;2. 性能下降&#xff1a;3. 延迟累积&#xff1a;4. 系统资源…

深入浅出Pytorch函数——torch.sort

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 按照值沿给定维度对输入张量的元素进行排序。如果未给定dim&#xff0c;则选择输入的最后一个维度。若descending被指定为True&#xff0c;则元素按值降序排列&#xff0c;否则为升序。如果stable为True&#xff0c;则排序例…

【C++】STL---list基本用法介绍

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

Kotlin基础(七):数据类和封闭类

前言 本文主要讲解kotlin数据类&#xff08;DataClass&#xff09;和封闭类&#xff08;SealedClasses&#xff09;&#xff0c;包括使用数据类&#xff0c;对象复制&#xff0c;数据类成员的解构&#xff0c;使用封闭类&#xff0c;以及数据类和封闭类在Android开发中的应用。…

el-select和el-checkBox实现下拉菜单全选功能

el-select 和 el-checkbox 实现下拉菜单全选功能 示例代码&#xff1a; <el-selectpopper-class"select-container"v-model"ids"placeholder"请选择目标":multiple-limit"20"multiplefilterablecollapse-tagsclass"wd400&qu…

ModuleNotFoundError: No module named ‘sklearn‘ 应该如何解决

该错误提示表明你的环境中缺少名为 sklearn 的模块&#xff0c;也就是 scikit-learn 包 要解决这个问题&#xff0c;你可以尝试以下几个步骤&#xff1a; 确认是否安装了 scikit-learn&#xff1a;请确保你已经在你的环境中安装了 scikit-learn。你可以使用以下命令来安装&am…

Debezium系列之:使用 Strimzi 将 Kafka 和 Debezium 迁移到 Kubernetes

Debezium系列之:使用 Strimzi 将 Kafka 和 Debezium 迁移到 Kubernetes 一、Kubernetes二、认识Strimzi三、安装 Strimzi四、创建Kafka集群五、创建Kafka Topic六、部署 Debezium Kafka Connect七、总结在本文中,将探讨在生产中实现debezium与K8s的结合: 在 Kubernetes 集群…

uniapp 小程序 查看评价

查看评价效果图&#xff1a; 评分组件在上一篇文章&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; <template><view class"view-comments"><view class"evaluate-box"><view class"ti…

使用Gin框架搭配WebSocket完成实时聊天

文章目录 前言实时聊天聊天功能测试发送信息 前言 在写项目的时候&#xff0c;需要完成实时聊天的功能&#xff0c;于是简单的学习下WebSocket&#xff0c;想知道WebSocket是什么的小伙伴可以去网上别的地方学习一下。 要实现实时聊天&#xff0c;网上的大部分内容都是Spring…

MacBookPro安装Win10,Wifi不能用了,触控板不能用了

由于工作需要&#xff0c;得在MacBookPro 2016上安装Windows系统&#xff1b;但是偶尔也需要用Mac系统&#xff0c;只好安装双系统。 苹果提供的双系统安装方案还是相当好用的&#xff1a;“启动转换助理”。去年安装完Win10后&#xff0c;触控板本身就支持双点相当于鼠标右键…

Ubuntu环境Docker安装

目录 一、什么是Docker概述 二、什么是容器&#xff1f; 三、什么是容器映像&#xff1f; 四、Ubuntu环境Docker安装 卸载旧版本&#xff08;可选&#xff09; 安装依赖 添加Docker官方GPG密钥 添加Docker APT源 安装Docker Engine 启动Docker服务 验证Docker安装 一…

Rust操作MySQL

查询 本部分是对 「Rust入门系列」Rust 中使用 MySQL[1]的学习与记录 经常使用的时间处理库&#xff1a; chrono 流式查询使用&#xff1a; query_iter 输出到Vec使用&#xff1a; query 映射到结构体使用&#xff1a; query_map 获取单条数据使用&#xff1a; query_first 命名…

小程序体验版上线注意事项

1.接口域名必须是https&#xff0c;有ssh证书。不能用ip地址。 2.需要在微信公众平台进行配置 微信公众平台->开发-> 开发管理->开发设置 对服务器域名和业务域名进行配置对业务域名进行配置时&#xff0c;需要下载校验文件&#xff0c;放在域名根目录下

【Node.js 安装】Node.js安装与使用教程

Node.js 安装 Node.js 是什么那什么是运行时 如何安装 Node.jsNode 使用教程 Node.js 是什么 先说结论&#xff0c;Node.js 它是一套 JavaScript 运行环境&#xff0c;用来支持 JavaScript 代码的执行 JavaScript 诞生于 1995 年&#xff0c;几乎是和互联网同时出现&#xf…

十分钟掌握 Vim 编辑器核心功能

十分钟掌握 Vim 编辑器核心功能 文章目录 十分钟掌握 Vim 编辑器核心功能&#x1f468;‍&#x1f3eb;内容一&#xff1a;前言【Vim是什么】&#x1f468;‍&#x1f52c;内容二&#xff1a;Vim 常用模式&#x1f468;‍&#x1f680;内容三&#xff1a;基本操作&#x1f468;…