文件上传
在Spring MVC中有两种实现上传文件的办法,第一种是Servlet3.0以下的版本通过commons-fileupload与commons-io完成的通用上传,第二种是Servlet3.0以上的版本通过Spring内置标准上传,不需借助第3方组件。通用上传也兼容Servlet3.0以上的版本。
一、Servlet3.0以下版本
1. 添加上传依赖包
因为需要借助第三方上传组件commons-fileupload与commons-io,所以要修改pom.xml文件添加依赖。
<!--文件上传 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2. 新增上传页面upload1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传文件</title>
</head>
<body>
<h2>上传文件</h2>
<form action="fileSave" method="post" enctype="multipart/form-data">
<p>
<label for="files">文件:</label> <input type="file" name="files" id="files" multiple="multiple" />
</p>
<p>
<button>提交</button>
</p>
<p>${message}</p>
</form>
</body>
</html>
需要注意的关键点:
- method的值必为Post;
- enctype必须为multipart/form-data,该类型的编码格式专门用于二进制数据类型;
- 上传表单元素必须拥有name属性;
3. 修改配置文件,增加上传配置
默认情总下Spring MVC对文件上传的视图内容是不能解析的,需要修改springmvc-servlet.xml配置文件配置一个CommonsMultipartResolver类型的解析器解析上传的内容。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="10485760000" />
<property name="maxInMemorySize" value="40960" />
</bean>
其具有的各属性的意义如下:
- defaultEncoding:默认编码格式
- maxUploadSize:上传文件最大限制(字节byte)
- maxInMemorySize:缓冲区大小
当Spring的前置中心控制器接收到客户端发送的一个多分部请求,定义在上下文中的解析器将被激活并开始处理。解析器将当前的HttpServletRequest包装成一个支持多部分文件上传的MultipartHttpServletRequest对象,在控制器中可以获得上传的文件信息。
- CommonsMultipartResolver用于通用的文件上传,支持各种版本的Servlet。
- StandardServletMultipartResolver用于Servlet3.0以上的版本上传文件。
4. 增加控制器与Action
package org.spring.mvc.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
@Controller
@RequestMapping("/upload")
public class FileUploadController {
@RequestMapping("/file1")
public String file1(Model model) {
return "upload/upload1";
}
@RequestMapping(value = "/fileSave", method = RequestMethod.POST)
public String fileSave(Model model, MultipartFile[] files, HttpServletRequest request) throws Exception {
for (MultipartFile file : files) {
System.out.println(file.getOriginalFilename());
System.out.println(file.getSize());
System.out.println("--------------------------");
File tempFile = new File("D:/", file.getOriginalFilename());
file.transferTo(tempFile);
}
return "upload/upload1";
}
}
注意这里定义的是一个MultipartFile数组,可以接受多个文件上传,如果单文件上传可以修改为MultipartFile类型;另外上传文件的细节在这里并没有花时间处理,比如文件重名的问题,路径问题,关于重名最简单的办法是重新命名为GUID文件名。
5. 测试运行
访问路径:http://localhost:8080/spring-mvc/upload/file1,运行结果如图1所示:
图 1
选择三个文件file1.txt,file2.txt,file3.txt,点击提交。
图 2
控制台输出:
file1.txt
15
--------------------------
file2.txt
15
--------------------------
file3.txt
15
--------------------------
图 3
二、Servlet3.0以上版本
Servlet3.0以上的版本不再需要第三方组件Commons.io和commons-fileupload,上传的方式与4.1提到基本一样,但配置稍有区别,可以使用@MultipartConfig注解在Servlet上进行配置上传,也可以在web.xml上进行配置。
1. 修改web.xml配置上传参数
<!--Servlet3.0以上文件上传配置 -->
<multipart-config>
<max-file-size>5242880</max-file-size><!--上传单个文件的最大限制5MB -->
<max-request-size>20971520</max-request-size><!--请求的最大限制20MB,一次上传多个文件时一共的大小 -->
<file-size-threshold>0</file-size-threshold><!--当文件的大小超过临界值时将写入磁盘 -->
</multipart-config>
multipart-config的各参数含义如下:
- file-size-threshold:数字类型,当文件大小超过指定的大小后将写入到硬盘上。默认是0,表示所有大小的文件上传后都会作为一个临时文件写入到硬盘上。
- location:指定上传文件存放的目录。当我们指定了location后,我们在调用Part的write(String fileName)方法把文件写入到硬盘的时候可以,文件名称可以不用带路径,但是如果fileName带了绝对路径,那将以fileName所带路径为准把文件写入磁盘,不建议指定。
- max-file-size:数值类型,表示单个文件的最大大小。默认为-1,表示不限制。当有单个文件的大小超过了max-file-size指定的值时将抛出IllegalStateException异常。
- max-request-size:数值类型,表示一次上传文件的最大大小。默认为-1,表示不限制。当上传时所有文件的大小超过了max-request-size时也将抛出IllegalStateException异常。
2. 修改pom.xml依赖信息
删除pom.xml中对文件上传第三方的依赖。
3. 修改springmvc-servlet.xml配置信息
将原有的文件上传通用解析器更换为标准解析器:
<!--文件上传解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>
4. 定义视图
在view/up/下定义名称为upload2.jsp文件:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传文件 - Servlet3.0</title>
</head>
<body>
<h2>上传文件 - Servlet3.0</h2>
<form action="file3Save" method="post" enctype="multipart/form-data">
<p>
<label for="files">文件:</label> <input type="file" name="files" id="files" multiple="multiple" />
</p>
<p>
<button>提交</button>
</p>
<p>${message}</p>
</form>
</body>
</html>
5. 定义Action
@RequestMapping("/file2")
public String file2(Model model){
return "upload/upload2";
}
@RequestMapping(value="/file3Save", method=RequestMethod.POST)
public String file3Save(Model model,MultipartFile[] files, HttpServletRequest request) throws Exception{
for (MultipartFile file : files) {
System.out.println(file.getOriginalFilename());
System.out.println(file.getSize());
System.out.println("--------------------------");
File tempFile=new File(file.getOriginalFilename());
file.transferTo(tempFile);
}
return "upload/upload2";
}