为了能上传文件,必须将表单的 method 设置为 POST,并将 enctype 设置为 multipart/form-data。这样浏览器会采用二进制流的方式来处理表单数据。
有两种方式来进行文件上传:
- 利用 Servlet 3.0 及更高版本的支持,但这种上传需要在 Servlet 中完成。
- SpringMVC 中使用 MultipartFile 对象,该接口依赖于Apache Commons FileUpload 组件,因此需要引入
commons-fileupload
。
在 HTML5之前,想要上传多个文件,就必须使用多个文件 input 元素。但是在 HTML5 中编写以下任意一行代码,即可生成一个按钮选择多个文件:
1
2
3
4 ><input type="file" name="fileName" multiple/>
><input type="file" name="fileName" multiple="multiple"/>
><input type="file" name="fileName" multiple=""/>
>
使用 SpringMVC 提供文件上传支持
在负责上传的表单设置编码为 “multipart/form-data”:1
2
3
4<form action="upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>
在请求方法中:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24@RequestMapping(value = "/uploadFiles")
public String uploadFile(HttpServletRequest request, @RequestParam("files") MultipartFile file) throws IOException
{
//如果上传文件非空,写入上传路径
if (!file.isEmpty())
{
//获取保存路径
String savePath = request.getSession().getServletContext().getRealPath("/uploadFiles/");
//上传文件名
String uploadFileName = file.getOriginalFilename();
File filepath=new File(savePath,uploadFileName);
if (!filepath.getParentFile().exists())
{
filepath.getParentFile().mkdir();
}
file.transferTo(new File(savePath+File.separator+uploadFileName));
request.setAttribute("message","文件上传成功");
} else
{
request.setAttribute("message","文件上传异常");
}
return "fileUpload";
}
要使用 SpringMVC 的文件上传功能,还需要在配置文件中配置 MultipartResolver:1
2
3
4
5
6
7
8
9
10<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件大小上限,单位为字节 -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
<!-- 请求的编码格式,必须和 JSP 的 pageEncoding 属性一致,以便正确读取表单的内容,默认为 ISO-8859-1 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
MultipartFile 对象中的常用方法有:
- byte[] getBytes():获取文件数据。
- String getContentType():获取文件 MIME 类型,如 image/jpeg 等。
- InputStream getInputStream():获取文件流。
- String getName():获取表单中文件组件的名字。
- String getOriginalFilename():获取上传文件的原名。
- long getSiez():获取文件的字节大小,单位为 byte。
- boolean isEmpty():是否有上传的文件。
- void transferTo(File dest):将上传文件保存到一个目标文件中。
利用 Servlet 3 及更高版本上传文件
利用 Servlet3 进行文件上传,需要在 web.xml 中对 servlet 元素进行改造,1
2
3
4
5
6
7
8<servlet>
.....
<multipart-config>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
@MultipartConfig
有如下可选属性:
- maxFileSize:上传文件的最大容量,默认值为 -1,表示没有限制。大于指定值的文件将会被拒绝。
- maxRequestSize:表示多部分 HTTP 请求允许的最大容量,默认值为 -1,表示没有限制。
- location:表示在 Part 调用 write 方法时,要将已上传的文件保存到硬盘中的位置。
- fileSizeThreshold:上传文件超出这个容量界限时,会被写入硬盘。
此外,还需要在 SpringMVC 配置文件中使用一个不同的多部分解析器:1
2<!-- 设置一个多部分解析器来进行基于 Servlet3 的文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
客户端上传
在 Servlet 中进行文件上传并不能显示上传的进度,或者显示已经成功上传的文件数量,用户体验很差。因此HTML5 在其 DOM 中添加了一个 File API,允许访问本地文件,通过 JavaScript 和该 File API 来提供报告上传进度的进度条。
(待补充)
文件下载
对于一些保存在应用程序目录外,或者是保存在某一个数据库中,或者有时需要控制它的访问权限,防止其他网站交叉引用的资源,可以通过编程来发送。通过编程进行的文件下载,可以有选择地将文件发送到浏览器。
通过编程把一个文件发送到浏览器,需要在控制器完成以下工作:
- 对请求处理方法使用 void 返回类型,并在方法中添加 HTTPServletResponse 参数。
- 将响应的内容类型设置为文件的内容类型,例如
response.setContentType("application/pdf"),如果不清楚内容类型,并且希望浏览器始终显示
Save As(另存为)对话框,可以将 ContentType 设置为 APPLICATION_OCTET_STREAM 。
- 添加一个名为 Content-Disposition 的 HTTP 响应标题,并赋值 attachment;filename=fileName,这里 fileName 默认是文件名,通常与文件同名。