当前位置:   article > 正文

Spring Boot 实现文件上传(多文件、扩展参数等)

Spring Boot 实现文件上传(多文件、扩展参数等)

前言

Spring允许我们使用可插拔的MultipartResolver对象启用多部分支持。该框架提供了

  • 一个Commons FileUpload的MultipartResolver实现
  • 以及另一个用于Servlet 3.0多部分请求解析的实现

Commons FileUpload

要使用CommonsMultipartResolver处理文件上传,我们需要添加以下依赖项:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

现在我们可以在我们的Spring配置中定义CommonsMultipartResolver bean。

这个MultipartResolver带有一系列set方法,用于定义属性,例如上传的最大大小:

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(100000);
    return multipartResolver;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里,我们需要在Bean定义本身中控制CommonsMultipartResolver的不同属性。

使用Servlet 3.0

为了使用Servlet 3.0多部分解析,我们需要配置几个应用程序。首先,我们需要在DispatcherServlet注册中设置MultipartConfigElement:

public class MainWebAppInitializer implements WebApplicationInitializer {

    private String TMP_FOLDER = "/tmp"; 
    private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; 
    
    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        
        ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(
          new GenericWebApplicationContext()));

        appServlet.setLoadOnStartup(1);
        
        MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, 
          MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
        
        appServlet.setMultipartConfig(multipartConfigElement);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

MultipartConfigElement对象中,我们配置了

  • 存储位置
  • 最大单个文件大小
  • 最大请求大小(在单个请求中有多个文件的情况下)
  • 以及将文件上传进度刷新到存储位置的大小。

这些设置必须在Servlet注册级别应用,因为Servlet 3.0不允许它们像CommonsMultipartResolver一样在MultipartResolver中注册。

完成此操作后,我们可以将StandardServletMultipartResolver添加到我们的Spring配置中:

@Bean
public StandardServletMultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}
  • 1
  • 2
  • 3
  • 4

单个文件上传

要上传文件,我们可以构建一个简单的表单,在其中使用类型为'file'的HTML输入标签。

无论选择哪种上传处理配置,我们都需要将表单的编码属性设置为multipart / form-data,这使浏览器知道如何对表单进行编码:

<form:form method="POST" action="/spring-mvc-xml/uploadFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td><form:label path="file">Select a file to upload</form:label></td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

要存储上传的文件,我们可以使用MultipartFile变量。我们可以从控制器方法内的request参数中检索此变量:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}
  • 1
  • 2
  • 3
  • 4
  • 5

该MultipartFile类提供访问有关上传文件的详细信息,包括文件名,文件类型,等等。我们可以使用一个简单的HTML页面来显示此信息:

<h2>Submitted File</h2>
<table>
    <tr>
        <td>OriginalFileName:</td>
        <td>${file.originalFilename}</td>
    </tr>
    <tr>
        <td>Type:</td>
        <td>${file.contentType}</td>
    </tr>
</table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

多个文件上传

要在一个请求中上传多个文件,我们只需将多个输入文件字段放在表单内:

<form:form method="POST" action="/spring-mvc-java/uploadMultiFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

我们需要注意每个输入字段都具有相同的名称,以便可以将其作为MultipartFile数组进行访问:

@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
    modelMap.addAttribute("files", files);
    return "fileUploadView";
}
  • 1
  • 2
  • 3
  • 4
  • 5

现在,我们可以简单地遍历该数组以显示文件信息:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>Spring MVC File Upload</title>
    </head>
    <body>
        <h2>Submitted Files</h2>
        <table>
            <c:forEach items="${files}" var="file">    
                <tr>
                    <td>OriginalFileName:</td>
                    <td>${file.originalFilename}</td>
                </tr>
                <tr>
                    <td>Type:</td>
                    <td>${file.contentType}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上传带有其他表单数据的文件

我们还可以将其他信息以及正在上传的文件发送到服务器。我们只需要在表单中包括必填字段:

<form:form method="POST" 
  action="/spring-mvc-java/uploadFileWithAddtionalData"
  enctype="multipart/form-data">
    <table>
        <tr>
            <td>Name</td>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr>
            <td>Email</td>
            <td><input type="text" name="email" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在控制器中,我们可以使用@RequestParam批注获取所有表单数据:

@PostMapping("/uploadFileWithAddtionalData")
public String submit(
  @RequestParam MultipartFile file, @RequestParam String name,
  @RequestParam String email, ModelMap modelMap) {

    modelMap.addAttribute("name", name);
    modelMap.addAttribute("email", email);
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

与前面的部分相似,我们可以使用带有JSTL标签的HTML页面来显示信息。

我们还可以将所有表单字段封装在模型类中,并在控制器中使用@ModelAttribute批注。当文件中有很多其他字段时,这将很有帮助。让我们看一下代码:

public class FormDataWithFile {

    private String name;
    private String email;
    private MultipartFile file;

    // standard getters and setters
}
@PostMapping("/uploadFileModelAttribute")
public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) {

    modelMap.addAttribute("formDataWithFile", formDataWithFile);
    return "fileUploadView";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Spring Boot 启动文件上传

Spring Boot使得配置和启动所有工作变得更加轻松。

只要我们将Web模块包括在我们的依赖项中,Boot将为我们注册并配置它,

很明显Boot给我们配置的是一个用于Servlet 3.0多部分请求解析的实现

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

如果要控制最大文件上传大小,则可以编辑application.properties

spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
  • 1
  • 2

我们还可以控制是否启用文件上传以及文件上传的位置:

spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}
  • 1
  • 2

请注意,我们已经使用$ {java.io.tmpdir}定义了上载位置,以便可以将临时位置用于不同的操作系统。

参考:
https://www.baeldung.com/spring-file-upload


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/239485
推荐阅读
相关标签