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

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());}}

 

http://www.lryc.cn/news/105278.html

相关文章:

  • 【E题】2023年电赛运动目标控制与自动追踪系统方案
  • 企业网络安全之零信任和身份认证
  • 【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5
  • [运维|中间件] 东方通TongWeb使用笔记
  • WIZnet W6100-EVB-Pico DHCP 配置教程(三)
  • 【Linux】Ansible 脚本 playbook 剧本
  • 解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题
  • 百度与AI:历史、投资和监管
  • Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)
  • 【图论】无向图连通性(tarjan算法)
  • Docker安装
  • 06. 计数原理
  • 计算机网络基础(静态路由,动态路由,公网IP,私网IP,NAT技术)
  • CGAL 点云Alpha-Shape曲面重建算法
  • Java 文件过滤器FileFilter | 按条件筛选文件
  • python格式化地址信息
  • k8s1.26.6 安装gitlab
  • C5.0决策树建立个人信用风险评估模型
  • 【k8s集群部署】使用containerd运行时部署kubernetes集群(V1.27版本)
  • 网络安全进阶学习第八课——信息收集
  • Spring Data Elasticsearch - 在Spring应用中操作Elasticsearch数据库
  • 图论-简明导读
  • 记一次 .NET 某物流API系统 CPU爆高分析
  • 【Docker】Docker安装Kibana服务_Docker+Elasticsearch+Kibana
  • 前端面试题-VUE
  • Linux嵌入式平台安全启动理解介绍
  • 安全学习DAY09_加密逆向,特征识别
  • 原型模式(Prototype)
  • 深度学习之用PyTorch实现线性回归
  • 45.248.11.X服务器防火墙是什么,具有什么作用