当前位置: 首页 > 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工程师去写…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...