Spring Mvc 文件上传(MultipartFile )—官方原版
一、创建应用程序类
要启动Spring Boot MVC应用程序,首先需要一个启动器。在这个示例中,已经添加了spring-boot-starter thymelaf和spring-boot-starter web作为依赖项。要使用Servlet容器上传文件,您需要注册一个MultipartConfigElement类(在web.xml中为<multipart-config>)。多亏了Spring Boot,一切都可以自动配置!
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
2、创建UploadingFilesApplication
开始使用此应用程序所需的只是以下UploadingFilesApplication类(来自src/main/java.com/example/uploadingfiles/UploadingFilesApplication.java):
package com.example.uploadingfiles;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class UploadingFilesApplication {public static void main(String[] args) {SpringApplication.run(UploadingFilesApplication.class, args);}}
二、创建文件上传控制器
最初的应用程序已经包含了一些类来处理在磁盘上存储和加载上传的文件。它们都位于com.example.uploadingfiles.storage包中。您将在新的FileUploadController中使用这些。以下列表(来自src/main/java.com/example/uploadingfiles/FileUploadController.java)显示了文件上传控制器:
package com.example.uploadingfiles;import java.io.IOException;
import java.util.stream.Collectors;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;import com.example.uploadingfiles.storage.StorageFileNotFoundException;
import com.example.uploadingfiles.storage.StorageService;@Controller
public class FileUploadController {private final StorageService storageService;@Autowiredpublic FileUploadController(StorageService storageService) {this.storageService = storageService;}@GetMapping("/")public String listUploadedFiles(Model model) throws IOException {model.addAttribute("files", storageService.loadAll().map(path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class,"serveFile", path.getFileName().toString()).build().toUri().toString()).collect(Collectors.toList()));return "uploadForm";}@GetMapping("/files/{filename:.+}")@ResponseBodypublic ResponseEntity<Resource> serveFile(@PathVariable String filename) {Resource file = storageService.loadAsResource(filename);return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=\"" + file.getFilename() + "\"").body(file);}@PostMapping("/")public String handleFileUpload(@RequestParam("file") MultipartFile file,RedirectAttributes redirectAttributes) {storageService.store(file);redirectAttributes.addFlashAttribute("message","You successfully uploaded " + file.getOriginalFilename() + "!");return "redirect:/";}@ExceptionHandler(StorageFileNotFoundException.class)public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {return ResponseEntity.notFound().build();}}
FileUploadController类使用@Controller进行注释,以便Spring MVC可以拾取它并查找路由。每个方法都用@GetMapping或@PostMapping标记,以将路径和HTTP操作与特定的控制器操作联系起来。
在这种情况下:
-
GET/:从StorageService查找当前上载文件的列表,并将其加载到Thymelaf模板中。它使用MvcUriComponentsBuilder计算到实际资源的链接。
-
GET/files/{filename}:加载资源(如果存在),并使用Content-Disposition响应标头将其发送到浏览器进行下载。
-
POST/:处理由多部分组成的消息文件,并将其提供给StorageService进行保存。
您需要提供StorageService,以便控制器可以与存储层(如文件系统)进行交互。以下列表(来自src/main/java.com/example/uploadingfiles/storage/StorageService.java)显示了该接口:
package com.example.uploadingfiles.storage;import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;import java.nio.file.Path;
import java.util.stream.Stream;public interface StorageService {void init();void store(MultipartFile file);Stream<Path> loadAll();Path load(String filename);Resource loadAsResource(String filename);void deleteAll();}
三、创建 HTML 模板
以下Thymelaf模板(来自src/main/resources/templates/uploadForm.html)显示了如何上传文件并显示已上传内容的示例:
<html xmlns:th="https://www.thymeleaf.org">
<body><div th:if="${message}"><h2 th:text="${message}"/></div><div><form method="POST" enctype="multipart/form-data" action="/"><table><tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr><tr><td></td><td><input type="submit" value="Upload" /></td></tr></table></form></div><div><ul><li th:each="file : ${files}"><a th:href="${file}" th:text="${file}" /></li></ul></div></body>
</html>
此模板由三部分组成:
-
顶部的一个可选消息,Spring MVC在其中写入一个flash范围的消息。
-
允许用户上传文件的表单。
-
从后端提供的文件列表。
四、调整文件上传限制
配置文件上载时,设置文件大小限制通常很有用。想象一下,试图处理5GB的文件上传!使用Spring Boot,我们可以通过一些属性设置来调整其自动配置的MultipartConfigElement。
将以下财产添加到现有财产设置中(在src/main/resources/application.nenenebc属性中):
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
多部分设置的约束如下:
-
spring.servlet.multipart.max-file-size设置为 128KB,表示总文件大小不能超过 128KB。
-
spring.servlet.multipart.max-request-size设置为 128KB,这意味着 的总请求大小不能超过 128KB。multipart/form-data
五、运行应用程序
您想要一个上传文件的目标文件夹,因此需要增强Spring Initializer创建的基本UploadingFilesApplication类,并添加Boot CommandLineRunner以在启动时删除并重新创建该文件夹。以下列表(来自src/main/java.com/example/uploadingfiles/UploadingFilesApplication.java)显示了如何做到这一点:
package com.example.uploadingfiles;import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;import com.example.uploadingfiles.storage.StorageProperties;
import com.example.uploadingfiles.storage.StorageService;@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class UploadingFilesApplication {public static void main(String[] args) {SpringApplication.run(UploadingFilesApplication.class, args);}@BeanCommandLineRunner init(StorageService storageService) {return (args) -> {storageService.deleteAll();storageService.init();};}
}
@SpringBootApplication是一个方便的注释,它添加了以下所有内容:
@配置:将类标记为应用程序上下文的bean定义的源。
@EnableAutoConfiguration:告诉SpringBoot开始基于类路径设置、其他bean和各种属性设置添加bean。例如,如果spring-webmvc在类路径上,则此注释将应用程序标记为web应用程序并激活关键行为,例如设置DispatcherServlet。
@ComponentScan:告诉Spring在com/example包中查找其他组件、配置和服务,让它找到控制器。
main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。您注意到没有一行XML吗?也没有web.xml文件。这个web应用程序是100%纯Java的,您不需要配置任何管道或基础设施。
六、测试
有多种方法可以在我们的应用程序中测试这一特定功能。下面的列表(来自src/test/java.com/example/uploadingfiles/FileUploadTests.java)显示了一个使用MockMvc的示例,这样就不需要启动servlet容器:
package com.example.uploadingfiles;import java.nio.file.Paths;
import java.util.stream.Stream;import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;import com.example.uploadingfiles.storage.StorageFileNotFoundException;
import com.example.uploadingfiles.storage.StorageService;@AutoConfigureMockMvc
@SpringBootTest
public class FileUploadTests {@Autowiredprivate MockMvc mvc;@MockBeanprivate StorageService storageService;@Testpublic void shouldListAllFiles() throws Exception {given(this.storageService.loadAll()).willReturn(Stream.of(Paths.get("first.txt"), Paths.get("second.txt")));this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(model().attribute("files",Matchers.contains("http://localhost/files/first.txt","http://localhost/files/second.txt")));}@Testpublic void shouldSaveUploadedFile() throws Exception {MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt","text/plain", "Spring Framework".getBytes());this.mvc.perform(multipart("/").file(multipartFile)).andExpect(status().isFound()).andExpect(header().string("Location", "/"));then(this.storageService).should().store(multipartFile);}@SuppressWarnings("unchecked")@Testpublic void should404WhenMissingFile() throws Exception {given(this.storageService.loadAsResource("test.txt")).willThrow(StorageFileNotFoundException.class);this.mvc.perform(get("/files/test.txt")).andExpect(status().isNotFound());}}
相关文章:
Spring Mvc 文件上传(MultipartFile )—官方原版
一、创建应用程序类 要启动Spring Boot MVC应用程序,首先需要一个启动器。在这个示例中,已经添加了spring-boot-starter thymelaf和spring-boot-starter web作为依赖项。要使用Servlet容器上传文件,您需要注册一个MultipartConfigElement类&…...
【E题】2023年电赛运动目标控制与自动追踪系统方案
系统的设计和制作可以按照以下步骤进行: 设计红色光斑位置控制系统: 选择合适的红色激光笔,并将其固定在一个二维电控云台上。 使用电机和编码器来控制电控云台的水平和垂直运动。 设计一个控制电路,可以通过输入控制信号来控制…...
企业网络安全之零信任和身份认证
零信任并不是一种技术,而是一个安全概念,是一种建立安全战略的理念、方法和框架。 零信任提供了一系列概念和思想,其中心思想是怀疑一切,否定一切,不再以网络边界为限,不能再将内部网络定义为可信任的&…...

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...
[运维|中间件] 东方通TongWeb使用笔记
参考文献 东方通tongweb部署服务 东方通tongweb部署服务 使用笔记 默认访问地址 http://ip:9060/console/默认用户名密码 TongWeb7.0默认用户名密码:thanos,thanos123.com...

WIZnet W6100-EVB-Pico DHCP 配置教程(三)
前言 在上一章节中我们讲了网络信息配置,那些网络信息的配置都是用户手动的去配置的,为了能跟电脑处于同一网段,且电脑能成功ping通板子,我们不仅要注意子网掩码,对于IP地址主机位和网络位的划分,而且还要注…...
【Linux】Ansible 脚本 playbook 剧本
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Ansible 脚本 playbook 剧本 playbook 剧本Templates 模块tags 模块Roles 模块在一个 playbook 中使用 roles 的步骤 playbook 剧本 playbooks 本身由以下各部分组成 &#…...

解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题
在安装完tensorflow库后出现 问题详述: ImportError: Could not find the DLL(s) msvcp140_1.dll. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downlo…...

百度与AI:历史、投资和监管
来源:猛兽财经 作者:猛兽财经 百度的人工智能在中国具有先发优势 随着ChatGPT的爆火,人工智能重新引起了投资者的注意,然而人工智能并不是突然爆火的,而是全球众多公司在人工智能技术上进行数十年如一日的研发和积累&a…...

Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)
目录 一、启动zookeeper集群及kafka集群服务启动1.1、先启动三台zookeeper集群服务,再启动三台kafka集群服务1.2、使用PrettyZoo连接zookeeper客户端工具 二、在zookeeper服务端存储的Kafka相关信息 一、启动zookeeper集群及kafka集群服务启动 1.1、先启动三台zook…...

【图论】无向图连通性(tarjan算法)
割边:dfn[u]<low[v] 割点:dfn[u]<low[v] (若为根节点,要有两个v这样的点) 一.知识点: 1.连通: 在图论中,连通性是指一个无向图中的任意两个顶点之间存在路径。如果对于图中的任意两个顶点 u 和 v&…...

Docker安装
Docker实践 yum安装 YUM源可以使用官方YUM源、清华大学开源镜像站配置YUM源,也可以使用阿里云开源镜像站提供的YUM源,建议选择使用阿里云开源镜像站提供的YUM源,原因速度快。 地址: https://developer.aliyun.com/mirror/ 我们安装ce版 …...
06. 计数原理
6. 计数原理 6.1 分类加法计数原理与分步乘法计数原理 分类加法计数原理定义 完成一件事,有 n n n 类办法,在第1类办法中有 m 1 m_1 m1 种不同的方法,在第2类办法中有 m 2 m_2 m2 种不同的方法,…,在第 n n…...

计算机网络基础(静态路由,动态路由,公网IP,私网IP,NAT技术)
文章目录 一:静态路由和动态路由二:静态路由的配置路由信息的方式演示三:默认路由四:公网IP和私网IP和NAT技术的基本理解 一:静态路由和动态路由 在说静态路由和动态路由前,我们需要来了解一下࿰…...
CGAL 点云Alpha-Shape曲面重建算法
文章目录 一、简介二、相关参数三、实现代码四、实现效果参考资料一、简介 在数学上, a l p h a − s h a p e alpha-shape a...
Java 文件过滤器FileFilter | 按条件筛选文件
文章目录 一、概述1.1 何时会用到文件过滤器1.2 工作流程1.3 常用的接口和类1.4 文件过滤器的作用 二、按文件属性过滤2.1 按前缀或后缀过滤文件名2.2 按文件大小过滤 三、按文件内容过滤3.1 文本文件过滤器3.1.1 根据关键字过滤文件内容3.1.2 使用正则表达式过滤文件内容 3.2 …...

python格式化地址信息
背景 最近在折腾一个好玩的库,capa 实现地址的格式化输出。我看的教程是这样的: location_str ["徐汇区虹漕路461号58号楼5楼", "泉州市洛江区万安塘西工业区"] import cpca df cpca.transform(location_str) df在正式的运行代码…...
k8s1.26.6 安装gitlab
Gitlab官方提供了 Helm 的方式在 Kubernetes 集群中来快速安装,但是在使用的过程中发现 Helm 提供的 Chart 包中有很多其他额外的配置,所以我们这里使用自定义的方式来安装,也就是自己来定义一些资源清单文件。 Gitlab主要涉及到3个应用&…...

C5.0决策树建立个人信用风险评估模型
通过构建自动化的信用评分模型,以在线方式进行即时的信贷审批能够为银行节约很多人工成本。本案例,我们将使用C5.0决策树算法建立一个简单的个人信用风险评估模型。 导入类库 读取数据 #创建编码所用的数据字典 col_dicts{} #要编码的属性集 cols [che…...
【k8s集群部署】使用containerd运行时部署kubernetes集群(V1.27版本)
【k8s集群部署】使用containerd运行时部署kubernetes集群(V1.27版本) 一、本次实践介绍1.1 环境规划介绍1.2 本次实践简介二、三台主机基础环境配置2.1 主机配置工作2.2 关闭防火墙和selinux2.3 关闭swap2.4 清空iptables2.5 配置时间同步2.6 修改内核参数2.7 配置hosts文件三…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...