文件的上传和下载--SpringMVC
文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载、邮件附件的上传和下载等。
接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解。
一.文件上传
多数文件上传都是通过表单形式提交给后台服务器的,因此,要实现文件上传功能,就需要提供一个文件上传的表单,而该表单必须满足以下3个条件:
1)form表单的method属性设置为post
2)form表单的enctype属性设置为multipart/form-data
3)提供<input type=”file” name=”filename” multiple=”multiple” />的文件上传输入框。
文件上传表单的实例代码如下:
<form action="uploadUrl" method="post" enctype="multipart/form-data"> <input type="file" name="filename" multiple="multiple" /> <input type="submit" value="文件上传" /> </form>
Spring MVC为文件上传提供了直接的支持,这种支持是通过MultipartResolver(多部件解析器)对象实现的。MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver来完成文件上传工作。在Spring MVC中使用MultipartResolver对象非常简单,只需要在配置文件中定义MultipartResolver接口的Bean即可,其具体配置方式如下:
<bean id=”multipartResolver” class=”org.springframework.web.multipart.commons.CommonsMultipartResolver”> <!-- 设置请求编码格式,必须与JSP中的pageEncoding属性一致 --> <property name=”defaultEncoding” value=”UTF-” /> <!-- 设置允许上传文件的最大值(2MB),单位为字节 --> <property name=”maxUploadSize” value=”” /> </bean>
通过<property>元素可以对文件解析类CommonsMultipartResolver的如下属性进行配置。
1)maxUploadSize:上传文件最大长度(以字节为单位)
2)maxInMemorySize:缓存中的最大尺寸
3)defaultEncoding:默认编码格式
4)resolverLazily:推迟文件解析,以便在Controller中捕获文件大小异常
注:在配置CommonsMultipartResolver时必须指定该Bean的id为multipartResolver
需要导入支持文件上传的相关JAR包,通过Apache官网地址“http://commons.apache.org/”下载(进入该网址后,在Apache Conmmons Proper下方列表的Components列中找到FileUpload和IO,单击链接后,即可在打开页面找到下载链接)具体如下:
1)commons-fileupload-1.3.2.jar
2)commons-io-2.5.jar
当完成页面表单和文件上传解析器的配置后,在Controller中编写文件上传的方法即可实现文件上传。文件上传的方法代码如下:
@Controller
public class FileUploadController {
@RequestMapping("fileUpload")
public String handleFormUpload(@RequestParam("name") String name,@RequestParam("filename") MultipartFile file,...) {
if(!file.isEmpty()) {
//具体的执行方法
...
return "uploadSuccess";//跳转到成功页面
}
return "uploadFailure";//跳转到失败页面
}
}
在上述代码中,包含一个MultipartFile接口类型的参数file,上传到程序中的文件就是被封装在该参数中的。org.springframework.web.multipart.MultipartFile接口中提供了获取上传文件、文件名称等方法,这些方法及说明如下表01所示:
|
方法 |
说明 |
|
byte[] getBytes() |
以字节数组的形式返回文件的内容 |
|
String getContentType() |
返回文件的内容类型 |
|
InputStream getInputStream() |
读取文件内容,返回一个InputStream流 |
|
String getName() |
获取多部件form表单的参数名称 |
|
String getOriginalFilename() |
获取上传文件的初始化名 |
|
long getSize() |
获取上传文件的大小,单位是字节 |
|
boolean isEmpty() |
判断上传的文件是否为空 |
|
void transferTo(File file) |
将上传文件保存到目标目录下 |
表01:MultipartFile接口中的主要方法
接下来我们用一个具体的案例来演示文件上传功能的实现,具体步骤如下:
(1)在eclipse中创建一个名为fileUpload的动态Web项目,将Spring MVC相关的JAR包以及支持文件上传下载的JAR包添加到项目的lib目录中。添加后的lib目录如图01所示:

图01:Spring MVC环境下文件上传下载的JAR包
(2)在web.xml文件中,配置Spring MVC的前端控制器等。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>fileUpload</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置 DispatcherServlet 前端控制器 -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 在此处调用 springmvc.xml 文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 在 tomcat 服务器启动的时候,最先加载它 -->
<load-on-startup></load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
(3)右键fileUpload项目,新建Source Floder文件夹(专门用来存放配置文件等),创建并编写Spring MVC的核心配置文件springmvc-config.xml,如文件01所示。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 定义组件扫描器,指定需要扫描的包 -->
<context:component-scan base-package="com.neuedu.controller"/>
<!-- 配置注解驱动 -->
<mvc:annotation-driven />
<!-- 定义视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 设置后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置文件上传解析器 MultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置请求编码格式 -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
文件01:springmvc-config.xml
(4)在WebContext目录下,创建一个用于上传文件的页面fileUpload.jsp,编辑后如文件02所示:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script>
//判断是否填写上传人并已选择上传文件
function check(){
var name = document.getElementById("name").value;
var file = document.getElementById("file").value;
if(name==""){
alert("请填写上传人");
return false;
}
||file==""){
alert("请选择上传文件");
return false;
}
return true;
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/fileUpload.action" method="post" enctype="multipart/form-data" onsubmit="return check()">
上传人:<input id="name" type="text" name="name" /><br />
请选择文件:<input id="file" type="file" name="uploadfile" multiple="multiple" />
<input type="submit" value="文件上传" />
</form>
</body>
</html>
文件02:fileUpload.jsp
(5)在WEB-INF目录下,创建jsp文件夹,并在文件夹中创建success.jsp和error.jsp文件,分别在两个文件的<body>元素内编写显示上传成功的信息(如:"文件上传成功!")和显示上传失败的信息(如"文件上传失败,请重新上传!")
(6)在src目录下,创建一个com.neuedu.controller包,在该包下创建一个用于文件上传的控制器类FileUploadController,如文件03所示:
package com.neuedu.controller;
import java.io.File;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
/*
* 文件上传
* */
@Controller
public class FileUploadController {
/*
* 执行文件上传
* */
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParam("name") String name,@RequestParam("uploadfile") List<MultipartFile> uploadfile,HttpServletRequest request) {
//判断所上传文件是否存在
) {
//循环输出上传的文件
for(MultipartFile file : uploadfile) {
//获取上传文件的原始名称
String originalFilename = file.getOriginalFilename();
//设置上传文件的保存地址目录
String dirPath = request.getServletContext().getRealPath("/upload/");
File filePath = new File(dirPath);
//如果保存文件的地址不存在,就先创建目录
if(!filePath.exists()) {
filePath.mkdirs();
}
//使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称)
String newFilename = name+"_"+UUID.randomUUID()+"_"+originalFilename;
try {
//使用MultipartFile接口的方法完成文件上传到指定位置
file.transferTo(new File(dirPath + newFilename));
}catch(Exception e) {
e.printStackTrace();
return "error";
}
}
//跳转的成功页面
return "success";
}else {
return "error";
}
}
}
文件03:FileUploadController.java
(7)将项目发布到Tomcat服务器中并启动,在浏览器中访问地址 http://localhost:8080/fileUpload/fileUpload.jsp,填写上传人,选择文件上传,效果如下图:

(8)如果成功上传,此时查看项目的发布目录,即可发现在fileUpload项目中多了一个upload文件夹,该文件夹存放着你所上传的文件,并且以"上传人_uuid_原始文件名称"的形式。
注意:upload文件夹是在项目的发布路径中,而不是创建的项目所在目录。如果未更改项目的发布路径,则要去工作空间的metadata目录中寻找项目发布目录(路径为:workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileUpload\upload);如果将项目的发布路径已经更改到Tomcat中,则需要在Tomcat的webapps目录中寻找项目。
至此,文件上传功能的实现演示完毕,整个项目目录如图02所示:

二.文件下载
文件下载就是将文件服务器中的文件下载到本机上。在Spring MVC环境中实现文件下载大致可分为如下两个步骤:
<1>在客户端页面使用一个文件下载的超链接,该链接的href属性要指定后台文件下载的方法和文件名(需要先在文件下载目录中添加一个名称为“1.jpg”的文件),具体代码实例如下:
<a href="${pageContext.request.contextPath }/download.action?filename=1.jpg">文件下载</a>
<2>在后台Controller类中,使用Spring MVC提供的文件下载方法进行文件下载。
Spring MVC提供了一个ResponseEntity类型的对象,使用它可以定义返回的HttpHeaders对象和HttpStatus对象,通过对这两个对象的设置,即可完成下载文件时所需的配置信息。文件下载的实例代码如下所示:
@RequestMapping("/download")
Public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception {
//指定要下载的文件所在路径
String path = request.getServletContext().getRealPath(“/upload/”);
//创建该文件对象
File file = new File(Path+File.separator+filename);
//设置响应头
HttpHeaders headers = new HttpHeaders();
//通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment",filename);
//定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//使用Spring MVC框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
接下来我们用一个具体的案例来演示文件下载功能的实现,具体步骤如下:
(1)按照之前的步骤搭建好环境和配置文件,创建一个页面文件fileDownload.jsp,将上面<1>步骤的代码插入body元素之间,如下文件04所示:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/fileDownload.action?filename=1.jpg">文件下载
</a>
</body>
</html>
文件04:fileDownload.jsp
(2)在src下新建com.neuedu.controller包,并在该包下新建FileUploadController,将上面<2>步骤的fileDownload()方法编写在FileUploadController类中。如文件05所示:
package com.neuedu.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class fileDownloadController {
@RequestMapping("/fileDownload")
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception {
//指定要下载的文件所在路径
String path = request.getServletContext().getRealPath("/upload/");
//创建该文件对象
File file = new File(path+File.separator+filename);
//设置响应头
HttpHeaders headers = new HttpHeaders();
//通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment",filename);
//定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//使用Spring MVC框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
}
文件05:FileUploadController.java
(3)发布项目并启动Tomcat服务器,在文件下载目录下 "workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileDownload"下新建一个文件夹"upload"(命名要和fileDownload()方法中的指定要下载的文件所在路径一样),将一个命名为"1.jpg"(命名要与超链接中的参数filename的属性值一致)的图片拖进upload文件夹中。
最后,在浏览器中访问地址http://localhost:8080/fileDownload/fileDownload.jsp,效果如下:

单击”文件下载“链接后,出现下载提示弹窗,如下图所示:

选择”保存文件“,并单击”确定“按钮后,即可下载该文件。(在浏览器的下载窗口就可看到所下载的文件啦!!!)
文件的下载功能的实现演示到此完毕,整个项目目录如图02所示:

中文名称的文件下载:
上面例子通过Spring MVC实现了文件下载功能,但此案例代码只适用于非中文名称的文件下载。当对中文名称的文件进行下载时,因为各个浏览器内部转码机制的不同,就会出现乱码和解析异常问题。
为解决浏览器中文件下载时中文名称的乱码问题,可以在前端页面发送请求前先对中文名进行统一编码,然后在后台控制器类中对文件名称进行相应的转码。
(1)在下载页面中对中文文件名编码。可以使用URLEncoder类中的encoder(String s,String enc)方法将中文转为UTF-8编码。该方法中第一个参数表示需要转码的字符串,第二个参数表示编码格式,fileDownload.jsp文件修改如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/fileDownload.action?filename=<%=URLEncoder.encode("壁纸.jpg","UTF-8")%>">文件下载
</a>
</body>
</html>
(2)修改控制器类FileUploadController中的fileDownload()方法,并增加对文件名进行编码的方法,代码如下:
package com.neuedu.controller;
import java.io.File;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class fileDownloadController {
@RequestMapping("/fileDownload")
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception {
//指定要下载的文件所在路径
String path = request.getServletContext().getRealPath("/upload/");
//创建该文件对象
File file = new File(path+File.separator+filename);
//对文件名编码,防止中文文件乱码
filename = this.getFilename(request, filename);
//设置响应头
HttpHeaders headers = new HttpHeaders();
//通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment",filename);
//定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//使用Spring MVC框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
/*
* 根据浏览器的不同进行编码设置,返回编码后文件名
* */
public String getFilename(HttpServletRequest request,String filename) throws Exception {
//IE不同版本User-Agent中出现的关键词
String[] IEBrowserKeyWords = {"MSIE","Trident","Edge"};
//获取请求头代理信息
String userAgent = request.getHeader("User-Agent");
for(String keyWord : IEBrowserKeyWords) {
if(userAgent.contains(keyWord)) {
//IE内核浏览器,统一为UTF-8编码显示
return URLEncoder.encode(filename,"UTF-8");
}
}
//火狐等其他浏览器统一为ISO-8859-1编码显示
return new String(filename.getBytes("UTF-8"),"ISO-8859-1");
}
}
(3)在项目文件下载目录创建的upload文件夹中命名一个“壁纸.jpg”的文件,运行效果如下:
转载请标明出处,谢谢~
文件的上传和下载--SpringMVC的更多相关文章
- 在SpringMVC框架下实现文件的 上传和 下载
在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...
- SpringMVC+Ajax实现文件批量上传和下载功能实例代码
需求: 文件批量上传,支持断点续传. 文件批量下载,支持断点续传. 使用JS能够实现批量下载,能够提供接口从指定url中下载文件并保存在本地指定路径中. 服务器不需要打包. 支持大文件断点下载.比如下 ...
- Spring MVC 实现文件的上传和下载
前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:“用什么技术来实现一般网页上文件的上传和下载?是框架还是Java中的IO流”.我回复他说:“使用Spring MVC框架可以做到这一点,因为Spri ...
- java实现ftp文件的上传与下载
最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...
- SecureCRT使用sz和rz命令进行文件的上传和下载
SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...
- 使用FTPClient进行文件服务器内文件的上传和下载
我用的FTPClient是由Apache组织的commons-net.jar包中的API,这个包用起来非常的方便,很容易上手.我在项目开发的过程中主要用到了文件的上传和下载功能,下面将我开发的代码贴出 ...
- iOS开发中文件的上传和下载功能的基本实现-备用
感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...
- Apache FtpServer 实现文件的上传和下载
1 下载需要的jar包 Ftp服务器实现文件的上传和下载,主要依赖jar包为: 2 搭建ftp服务器 参考Windows 上搭建Apache FtpServer,搭建ftp服务器 3 主要代码 在ec ...
- 初学Java Web(7)——文件的上传和下载
文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...
随机推荐
- 2049. [SDOI2008]Cave 洞穴勘测【LCT】
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- php官网下载的chm手册,源码字号太小的问题解决
首先,到官方网站上下载chm格式的文档,地址如下: http://php.net/downloads.php 如图,点击荧光笔标出链接 然后就可以看到各种语言版本的文档手册,可以选择中文版,并带有笔记 ...
- SQLSERVER 数据类型int、bigint、smallint 和 tinyint范围
[bigint] 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字).存储大小为 8 个字节. [int ...
- java学习笔记-JavaWeb篇四
86 文件上传基础 87 使用 fileupload 组件 88 文件上传案例_需求 89 文件上传案例_JS代码 90 文件上传案例_约束的可配置性 91 文件上传案例_总体步骤分析 92 文件上传 ...
- HDU 1316 (斐波那契数列,大数相加,大数比较大小)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1316 Recall the definition of the Fibonacci numbers: ...
- PHP DES加解密
test.php测试文件 <?php require_once('Des.php'); $des = new Des(); $data['a'] = 'a'; $data['b'] = 'b'; ...
- HO引擎近况20180111
明明想着10号更新了,怎么就忘了呢? 公司的项目又被砍了,几个同事被开,我又转到另外一下组了,难道真的是我到哪哪黄? 快过年了,今年公司年会就在附近,太好了不用想怎么编理由请假事了,还有可能中个奖品, ...
- 三星S5-PV210内存初始化
一.S5PV210时钟系统 时钟:一定频率的电信号. 时钟系统:基于CMOS工艺的高性能处理器时钟系统,集成PLL可以从内部触发,比从外部触发更快且更准确,能有效地避免一些与信号完整性相关的问题. ...
- AWVS使用手册
目录: 0×00.什么是Acunetix Web Vulnarability Scanner ( What is AWVS?) 0×01.AWVS安装过程.主要文件介绍.界面简介.主要操作区域简介(I ...
- 基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...