当前位置: 首页 > news >正文

【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 接口是简单有效的选择。

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

相关文章:

【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..…...

UE5.1移动端PreintegratedSkinBxDF解析

Part 1 头文件 MobileBasePassPixelShader.usf 主要看Main函数&#xff1a; #if MOBILE_MULTI_VIEWResolvedView ResolveView(BasePassInterpolants.MultiViewId); #elseResolvedView ResolveView(); #endif这玩意Shader文件找不到&#xff0c;感觉是个全局变量的东西。万幸…...

WebSocket心跳机制(笔记大全)

一、WebSocket心跳机制前端 前端实现WebSocket心跳机制的方式主要有两种&#xff1a; 使用setInterval定时发送心跳包。在前端监听到WebSocket的onclose()事件时&#xff0c;重新创建WebSocket连接。 第一种方式会对服务器造成很大的压力&#xff0c;因为即使WebSocket连接正…...

Spring Boot日志:SLF4J和Logback

日志的分类 SpringBoot中的日志库分为两种&#xff1a; 实现库&#xff1a;提供具体的日志实现&#xff0c;例如日志级别的控制、打印格式、输出目标等。外观库&#xff1a;自身不提供日志实现&#xff0c;而是对其他日志库进行封装&#xff0c;从而方便使用。基于外观模式实…...

[C++] C++入门第二篇 -- 引用 -- 内联函数inline -- auto+for

目录 1、引用 -- & 1.1 引用的概念 1.2 引用特性 1.3 常引用 -- 权限问题 1.4 引用的使用场景 1.4.1 做参数 1.4.2 做返回值 注意 1.5 传值、传引用的效率比较 1.6 引用和指针的区别 2、内联函数 2.1 概念 转存失败重新上传取消​编辑转存失败重新上传取消​编…...

Latex | 将MATLAB图并导入Latex中的方法

一、问题描述 用Latex时写paper时&#xff0c;要导入MATLAB生成的图进去 二、解决思路 &#xff08;1&#xff09;在MATLAB生成图片的窗口中&#xff0c;导出.eps矢量图 &#xff08;2&#xff09;把图上传到overleaf的目录 &#xff08;3&#xff09;在文中添加相应代码 三…...

JSON格式Python,Java,PHP等封装根据关键词搜索获取淘宝商品列表数据API

淘宝是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要用关键词搜索获取淘宝天猫商品列表&#xff0c;您可以通过开放平台的接口或者直接访问淘宝天猫商城的网页来获取商品列表详细信息。以下是两种常用方法的介绍&a…...

MySQL MHA高可用配置及故障切换

文章目录 一.MySQL MHA1.什么是MHA&#xff12;.&#xff2d;&#xff28;&#xff21;的组成&#xff12;.&#xff11;MHA Node (数据节点)&#xff12;.&#xff12;MHA Manager (管理节点) &#xff13;.&#xff2d;&#xff28;&#xff21;的特点&#xff14;.&#xf…...

PHP8知识详解:PHP8开发工具VS Code的安装

作为PHP8的开发工具有很多&#xff0c;具有IDE功能的有phpstorm、Visual Studio Code、Sublime Text、NetBeans、Eclipse、Codelobster、PHP Designer等&#xff0c;当然还有很多轻量的工具&#xff0c;比如Notepad、Editplus等。本文给你介绍的是万能编辑器Visual Studio Code…...

Sui Move与标准Move的有哪些区别和根本性创新

Sui网络将Sui Move作为其本地编程语言&#xff0c;使用Sui Move编写的apps利用Sui的共识机制&#xff0c;实现了令人印象深刻的交易性能。 然而&#xff0c;熟悉Move编程语言的开发者在探索Sui文档时可能会感到困惑&#xff0c;因为该文档着重介绍了对象和一些指令&#xff0c…...

构建自己的ChatGPT:从零开始构建个性化语言模型

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…...

【react】react18的学习(十二)– 底层原理(二)之 迭代器 iterator

迭代器iterator 是一种 ES6 规范&#xff0c;具有这种机制的数据结构才可以使用for of循环&#xff1a;返回每一项的值&#xff1b; 原型链具有Symbol.iterator属性的数据结构都具备&#xff1b;如数组、部分类数组、字符串等&#xff1b; 普通对象就不能用&#xff1b; for-…...

一遍过JavaSE基础知识

文章目录 前言安装Java Development Kit (JDK)安装jdk配置开发环境验证是否安装配置成功 编写第一个Java程序hello world运行Java程序的流程 数据类型和变量数据类型变量 程序逻辑控制条件语句循环语句跳转语句 数组声明和创建数组访问数组元素数组长度遍历数组多维数组 面向对…...

【云原生】Kubernetes之ConfigMap

ConfigMap ConfigMap 是一种 API 对象&#xff0c;用来将非机密性的数据保存到键值对中。使用时&#xff0c; Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件 ConfigMap 将你的环境配置信息和 容器镜像 解耦&#xff0c;便于应用配置的修改 说明&#xff1a;…...

8.python设计模式【组合模式】

内容&#xff1a;将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。角色&#xff1a; 抽象组建&#xff08;component&#xff09;叶子组建(Leaf)复合组建(Composite)客户端 (Client) UML 图 举个例子 需求&#xf…...

tkinter制作任意图形窗口

import tkinter from PIL import Image, ImageTkdog tkinter.Tk() # 设置图片描绘的坐标&#xff0c;注意乘号是字母x dog.geometry(500x500200100) # 不允许修改大小 dog.resizable(False, False) # 不显示标题栏 dog.overrideredirect(True) # 设置白色透明色&#xff0c;这…...

视频监控综合管理平台EasyCVR多分屏默认播放协议的配置优化

视频监控综合管理平台EasyCVR具备视频融合汇聚能力&#xff0c;TSINGSEE青犀视频平台基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;包括&#xff1a;NVR、IPC、视频编码器、无人机、车载设备、智能手持终端、移动执法仪等。国标GB28181视频平台Ea…...

2023杭电多校第三场 1012.Noblesse Code

传送门:Vjudge 前题提要:一道挺有意思的数论题.赛时对于这道题没什么想法,但是赛后细品之后其实感觉也就那么一回事.但是这种 更相损减术与辗转相除法 相转化的题目还是有点典的,需要好好消化一下. 首先看完题目.我们需要考虑的是 ( A , B ) (A,B) (A,B)与 ( a , b ) (a,b) (…...

ubuntu qt 环境变量配置

ubuntu设置qt环境变量 qt 安装路径为&#xff1a;/home/ljn/Qt5.12 包含bin等目录的路经&#xff1a;/home/ljn/Qt5.14.2/5.14.2/gcc_64 环境变量配置 打开配置文件&#xff1a; sudo gedit /etc/profile在底部添加&#xff1a; export PATH"/home/ljn/Qt5.14.2/Tool…...

按照Vue写WPF(0):功能实现

文章目录 前言VUE具有的功能如何专业到WPF上面 前言 我最近学了WPF之后我终于知道为什么WPF学习曲线那么陡峭了。因为WPF没有组件化的思想&#xff0c;或者说没有按照Vue一样去模板化开发。 为什么我推荐Vue的想法呢。因为Vue最大的特点就是模板化&#xff0c;让Vue工程师去写…...

短剧小程序三端互通:微信 / 抖音 / 快手数据同步,会员一键通用

短剧行业已进入全域流量、多端变现的时代。只做微信&#xff0c;公域起量慢&#xff1b;只做抖音快手&#xff0c;私域难沉淀、风控风险高。真正能长期盈利的玩家&#xff0c;都在布局三端互通—— 微信、抖音、快手小程序数据实时同步&#xff0c;会员权益一键通用&#xff0c…...

如何用ContextMenuManager轻松管理Windows右键菜单:终极效率提升指南

如何用ContextMenuManager轻松管理Windows右键菜单&#xff1a;终极效率提升指南 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是不是也经常被Windows右键菜…...

春联生成模型-中文-base:3步生成专业级春节对联

春联生成模型-中文-base&#xff1a;3步生成专业级春节对联 1. 认识你的AI春联助手 春节将至&#xff0c;家家户户都开始准备贴春联。但创作一副既工整又富有寓意的春联并非易事。春联生成模型-中文-base正是为解决这一需求而生的AI工具。 这个模型基于阿里达摩院AliceMind团…...

从‘电池’到‘胡萝卜’:聊聊构建YOLO生活垃圾数据集时遇到的坑与收获

从‘电池’到‘胡萝卜’&#xff1a;构建YOLO生活垃圾数据集的实战思考 去年夏天&#xff0c;我在自家小区做垃圾分类志愿者时&#xff0c;发现一个有趣现象&#xff1a;居民们对"1号电池属于有害垃圾"这类规则记得很牢&#xff0c;但面对"半个胡萝卜该扔哪个桶…...

微博内容备份工具:让数字记忆永久保存的高效方案

微博内容备份工具&#xff1a;让数字记忆永久保存的高效方案 【免费下载链接】Speechless 把新浪微博的内容&#xff0c;导出成 PDF 文件进行备份的 Chrome Extension。 项目地址: https://gitcode.com/gh_mirrors/sp/Speechless 当你精心整理的旅行见闻、重要的行业观察…...

5分钟上手BilibiliDown:Windows/Mac/Linux三平台通用的B站视频下载神器

5分钟上手BilibiliDown&#xff1a;Windows/Mac/Linux三平台通用的B站视频下载神器 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.…...

金融C++内存池配置的3种致命误配模式(第2种90%团队仍在用,已触发监管问询)

第一章&#xff1a;金融C内存池配置的监管合规性与性能本质在高频交易系统、实时风控引擎及清算结算平台等关键金融基础设施中&#xff0c;C内存池&#xff08;Memory Pool&#xff09;不仅是性能优化的核心机制&#xff0c;更是监管审计关注的重点对象。其配置方式直接影响内存…...

WebLaTex:革新学术写作体验的云端LaTeX解决方案

WebLaTex&#xff1a;革新学术写作体验的云端LaTeX解决方案 【免费下载链接】WebLaTex A complete alternative for Overleaf with VSCode Web Git Integration Copilot Grammar & Spell Checker Live Collaboration Support. Based on GitHub Codespace and Dev cont…...

穿透式监管是什么?终于有人把穿透式监管落地讲明白了!

最近&#xff0c;各位老板有没有发现各种审计、检查多起来了&#xff1f;国资委、集团总部的发文一个接一个&#xff0c;问题也越来越细致。最近大家都被穿透式监管这个词弄得有点紧张&#xff0c;害怕自己的企业那天也被点名。其实&#xff0c;穿透式监管对企业来说&#xff0…...

C++ 编译模型与工程机制全解析:从 include 到链接与 ABI

关键词&#xff1a;编译、链接、#include、本质、静态库、动态库、ABI 适合人群&#xff1a;有 Java / Android 背景&#xff0c;开始深入理解 C 工程机制的开发者一、为什么一定要理解“编译模型”&#xff1f;很多人写 C 会遇到这些问题&#xff1a;❓ 为什么 include 了还能…...