Spring MVC多种情况下进行文件上传的实例
作者:会洗碗的CV工程师
一、原生方式上传
上传是Web工程中很常见的功能,SpringMVC框架简化了文件上传的代码,我们首先使用JAVAEE原生方式上传文件来进行详细描述:
1.1 修改web.xml项目版本
这里我们创建新的SpringMVC模块,在web.xml中将项目从2.3改为3.1,即可默认开启el表达式,如下图:
1.2 上传JSP页面
那这里我们需要访问一个页面来进行文件下载
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>上传</title> </head> <body> <h3>文件上传</h3> <%-- 上传表单的提交方式必须是post --%> <%-- enctype属性为multipart/from-data,意思是不对表单数据进行编码 --%> <form action="/fileUpload" method="post" enctype="multipart/form-data"> <%-- 文件选择控件,类型是file,必须要有name属性 --%> 选择文件:<input type="file" name="upload"/> <input type="submit" value="上传"> </form> </body> </html>
1.3 引入文件上传依赖
接下来需要分析请求体中的文件项,并将数据写入磁盘,此时需要借助文件上传工具
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
1.4 分析控制器执行流程
编写控制器接收上传请求,控制器进行三步操作:
- 创建文件夹,存放上传文件。
- 分析请求体,找到上传文件数据。
- 将文件数据写入文件夹。
完整文件上传控制器代码如下:
package com.example.controller; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.List; import java.util.UUID; @Controller public class UploadController { @RequestMapping("/fileUpload") public String upload(HttpServletRequest request) throws Exception{ // 创建文件夹,存放上传文件 // 1.设置上传文件夹的真实路径 String realpath = request.getSession().getServletContext().getRealPath("/upload"); System.out.println(realpath); // 2.判断目录是否存在,如果不存在,创建该目录 File file = new File(realpath); if(!file.exists()){ file.mkdirs(); } // 分析请求体,找到上传文件数据 // 1.创建磁盘文件工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); // 2.创建上传数据分析器对象 ServletFileUpload servletFileUpload = new ServletFileUpload(factory); // 3.利用分析器对象解析请求体,返回所有数据项 List<FileItem> fileItems = servletFileUpload.parseRequest(request); // 遍历所有数据,找到文件项(非表单项) for(FileItem fileItem:fileItems){ if(!fileItem.isFormField()){ // 将文件数据写进文件夹 // 1.获取文件名 String name = fileItem.getName(); // 2.将文件写入磁盘 fileItem.write(new File(file,name)); System.out.println(file.getAbsoluteFile()); // 3.删除内存中的临时文件 fileItem.delete(); } } return "index"; } }
文件成功下载后跳转到默认页面。
1.5 测试结果
访问路径:http://localhost:8080/upload.jsp
点击选择文件,选择要上传的文件,然后点击上传。
OK,可以得到webapp目录下面多了一个文件夹upload,并且里面有我们刚刚上传的文件。 可以看得出来用原生的方式来完成文件上传是比较麻烦的,接下来我们看一下用Spring MVC方式如何来进行文件上传
二、Spring MVC 方式上传
SpringMVC使用框架提供的文件解析器对象,可以直接将请求体中的文件数据转为MultipartFile对象,从而省略原生上传中分析请求体的步骤。
2.1 配置文件解析器
<!-- 文件解析器对象,id名称必须是multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 支持一次上传文件的总容量。单位:字节100M = 100*1024*1024 --> <property name="maxUploadSize" value="104857600"/> <!-- 文件名的编码方式 --> <property name="defaultEncoding" value="utf-8"/> </bean>
2.2 创建JSP表单
upload2,.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>上传</title> </head> <body> <h3>文件上传</h3> <%-- 上传表单的提交方式必须是post --%> <%-- enctype属性为multipart/from-data,意思是不对表单数据进行编码 --%> <form action="/fileUpload2" method="post" enctype="multipart/form-data"> <%-- 文件选择控件,类型是file,必须要有name属性 --%> 选择文件:<input type="file" name="file"> <input type="submit" value="上传"> </form> </body> </html>
其实这个JSP和上面那个没什么区别,只是响应处理的路径不同,为了避免重复开关tomcat,因为就多编写了一个表单。
2.3 控制器方法
// MultipartFile参数名必须和JSP文件空间的name属性一致 @RequestMapping("/fileUpload2") public String upload2(MultipartFile file,HttpServletRequest request) throws Exception{ // 创建文件夹,存放上传文件 String realpath = request.getSession().getServletContext().getRealPath("/upload"); File dir = new File(realpath); if(!dir.exists()){ dir.mkdirs(); } // 将上传的数据写到文件夹的文件中 // 1.拿到上传的文件名 String filename = file.getOriginalFilename(); filename = UUID.randomUUID()+"_"+filename; // 2.创建空文件 File newFile = new File(dir,filename); // 3.将数据写入空文件中 file.transferTo(newFile); return "index"; }
Ok,可以看到这个比上面那个简单许多,只需要参数名和表单的name属性一致便可以自动匹配。
2.4 测试结果
OK,访问路径:http://localhost:8080/upload2.jsp
看到如下图,我们是成功上传了呢
三、上传多文件
SpringMVC支持一次性上传多个文件,写法如下:
3.1 JSP页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>上传</title> </head> <body> <h3>文件上传</h3> <%-- 上传表单的提交方式必须是post --%> <%-- enctype属性为multipart/from-data,意思是不对表单数据进行编码 --%> <form action="/fileUpload3" method="post" enctype="multipart/form-data"> <%-- 文件选择控件,类型是file,必须要有name属性 --%> 用户名:<input name="username"/><br/> 文件1:<input type="file" name="files"><br/> 文件2:<input type="file" name="files"><br/> <input type="submit" value="上传"> </form> </body> </html>
3.2 控制器方法
// 处理多文件上传,参数类型为MultipartFile数组参数名和JSP文件控件的name属性一致 @RequestMapping("/fileUpload3") public String upload3(MultipartFile files[],String username,HttpServletRequest request) throws Exception{ System.out.println(username); // 1.设置上传文件保存的文件夹 String realPath = request.getSession().getServletContext().getRealPath("/upload/files"); File dir = new File(realPath); if(!dir.exists()){ dir.mkdirs(); } // 2.遍历数组,将上传文件保存到文件夹 for(MultipartFile file:files){ String filename = file.getOriginalFilename(); filename = UUID.randomUUID()+"_" +filename; File newFile = new File(dir,filename); file.transferTo(newFile); } return "index"; }
这里我们可以知道,方法参数名改一下类型即可, 并且表单的文件name必须要一致,上传后的文件放在upload文件夹子文件夹files里。
3.3 测试结果
OK,如下图,我们是可以成功添加了files文件夹,并且里面也是有文件的
以上就是Spring MVC多种情况下进行文件上传的实例的详细内容,更多关于Spring MVC文件上传的资料请关注脚本之家其它相关文章!