学科分类
目录
Spring Boot开发

文件上传

开发Web应用时,文件上传是很常见的一个需求,浏览器通过表单形式将文件以流的形式传递给服务器,服务器对上传的数据解析处理。下面通过一个案例讲解如何使用Spring Boot实现文件上传,具体步骤如下:

1. 编写文件上传的表单页面

在chapter05项目根路径下的templates模板引擎文件夹下创建一个用来上传文件的upload.html模板页面,内容如文件1所示。

文件1 upload.html

 1    <!DOCTYPE html>
 2    <html lang="en" xmlns:th="http://www.thymeleaf.org">
 3    <head>
 4        <meta charset="UTF-8">
 5        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6        <title>动态添加文件上传列表</title>
 7        <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
 8        <script th:src="@{/login/js/jquery.min.js}"></script>
 9    </head>
 10    <body>
 11    <div th:if="${uploadStatus}" style="color: red" th:text="${uploadStatus}">上传成功</div>
 12        <form th:action="@{/uploadFile}" method="post" enctype="multipart/form-data">
 13            上传文件:&nbsp;&nbsp;<input type="button" value="添加文件" onclick="add()"/>
 14            <div id="file" style="margin-top: 10px;" th:value="文件上传区域">  </div>
 15            <input id="submit" type="submit" value="上传" 
 16                                                   style="display: none;margin-top: 10px;"/>
 17        </form>
 18    <script type="text/javascript">
 19        // 动态添加上传按钮
 20        function add(){
 21            var innerdiv = "<div>";
 22            innerdiv += "<input type='file' name='fileUpload' required='required'>" +
 23                           "<input type='button' value='删除' onclick='remove(this)'>";
 24            innerdiv +="</div>";
 25            $("#file").append(innerdiv);
 26            // 打开上传按钮
 27            $("#submit").css("display","block");
 28        }
 29        // 删除当前行<div>
 30        function remove(obj) {
 31            $(obj).parent().remove();
 32            if($("#file div").length ==0){
 33                $("#submit").css("display","none");
 34            }
 35        }
 36    </script>
 37    </body>
 38    </html>

文件1的内容主要分为3部分内容,第12~17行的<form>表单用来封装上传文件标签并进行表单提交,第11行中<form>表单上方的文件上传状态信息uploadStatus,第10~36行的<script>标签中用于动态添加/删除上传标签的方法。其中,<form>表单中进行文件上传时,必须设置enctype="multipart/form-data",并将method属性设置为post;<script>标签中的add和remove方法用于根据用户上传文件需求动态添加或移除上传输入框效果的。

另外在文件1中第8行代码还引入了静态资源目录下的login/js中的jquery.min.js文件,因此,这里需要在项目resources/static/login目录下创建一个js文件夹,并引入jquery.min.js文件。

1. 在全局配置文件中添加文件上传的相关配置

在全局配置文件application.properties中添加文件上传功能的相关设置,内容如文件2所示。

文件2 application.properties

 1    # thymeleaf页面缓存设置(默认为true),开发中方便调试应设置为false,上线稳定后应保持默认true
 2    spring.thymeleaf.cache=false
 3    # 配置国际化文件基础名
 4    spring.messages.basename=i18n.login
 5    # 单个上传文件大小限制(默认1MB)
 6    spring.servlet.multipart.max-file-size=10MB
 7    # 总上传文件大小限制(默认10MB)
 8    spring.servlet.multipart.max-request-size=50MB

文件2中,在项目全局配置文件application.properties已有配置的基础上,对文件上传过程中的上传大小进行了设置。其中,spring.servlet.multipart.max-file-size用来设置单个上传文件的大小限制,默认值为1MB;spring.servlet.multipart.max-request-size用来设置所有上传文件的大小限制,默认值为10MB。如果上传文件的大小超出默认值10MB,会出现“FileUploadBase$FileSizeLimitExceededException: The field fileUpload exceeds its maximum permitted size of 1048576 bytes”异常信息,这里需要开发者结合实际需求合理设置文件大小。

2. 进行文件上传处理实现文件上传功能

在之前创建的com.itheima.controller包下创建一个管理文件上传下载的控制类FileController,用于实现文件上传功能,内容如文件3所示。

文件3 FileController.java

 1    import org.springframework.stereotype.Controller;
 2    import org.springframework.ui.Model;
 3    import org.springframework.web.bind.annotation.*;
 4    import org.springframework.web.multipart.MultipartFile;
 5    import java.io.File;
 6    import java.util.UUID;
 7    /**
 8     * 文件管理控制类
 9     */
 10    @Controller
 11    public class FileController {
 12        // 向文件上传页面跳转
 13        @GetMapping("/toUpload")
 14        public String toUpload(){
 15            return "upload";
 16        }
 17        // 文件上传管理
 18        @PostMapping("/uploadFile")
 19        public String uploadFile(MultipartFile[] fileUpload, Model model) {
 20            // 默认文件上传成功,并返回状态信息
 21            model.addAttribute("uploadStatus", "上传成功!");
 22            for (MultipartFile file : fileUpload) {
 23                // 获取文件名以及后缀名
 24                String fileName = file.getOriginalFilename();
 25                // 重新生成文件名(根据具体情况生成对应文件名)
 26                fileName = UUID.randomUUID()+"_"+fileName;
 27                // 指定上传文件本地存储目录,不存在需要提前创建
 28                String dirPath = "F:/file/";
 29                File filePath = new File(dirPath);
 30                if(!filePath.exists()){
 31                    filePath.mkdirs();
 32                }
 33                try {
 34                    file.transferTo(new File(dirPath+fileName));
 35                } catch (Exception e) {
 36                    e.printStackTrace();
 37                    // 上传失败,返回失败信息
 38                    model.addAttribute("uploadStatus","上传失败: "+e.getMessage());
 39                }
 40            }
 41            // 携带上传状态信息回调到文件上传页面
 42            return "upload";
 43        }
 44    }

文件3中,toUpload()方法处理路径为“/toUpload”的GET请求,向文件上传页面upload.html跳转;uploadFile()方法处理路径为“/uploadFile”的POST请求,对上传文件进行处理。文件上传处理过程中,对文件名进行重命名并存放在“F:/file/”目录下,并封装了返回结果。其中,处理上传文件的请求方法中,使用了“MultipartFile[] fileUpload”参数处理单个或多个上传文件(也可以使用单列集合参数),fileUpload参数名必须与upload.html页面中上传文件<input>框中的name属性值一致。

1. 效果测试

启动项目,项目启动成功后,在浏览器上访问“http://localhost:8080/toUpload”,效果如图1所示。

图1 文件上传页面初始效果

单击图2中的【添加文件】按钮,能够动态添加多个文件,效果如图2所示。

图2 文件上传页面动态添加文件效果

如图2所示,在文件上传页面中动态添加了3个上传文件输入框,分别选择了doc、xlsx和pptx格式的文件进行上传。其中,在每一个上传文件输入框后还有对应的【删除】按钮,通过这个按钮可以将多余的上传文件输入框移除;同时,如果在单击【上传】按钮进行文件上传时有未选择的文件输入框,还会出现“请选择一个文件”的提示信息(通过页面required属性进行控制的)。

单击图2中的【上传】按钮进行上传处理,效果如图3所示。

图3 文件上传响应

如图4所示,选择的3个文件进行上传处理后页面出现了“上传成功!”的响应信息。为了验证文件上传处理效果,查看定制的上传文件存储目录“F:/file/”,效果如图4所示。

图4 文件上传处理结果

从图4可以看出,在定制的上传文件存储目录“F:/file/”下,出现了选择上传的3个不同类型的文件,同时文件名也根据设置进行了相应的修改,读者还可以打开每个文件查看具体的文件内容。

点击此处
隐藏目录