SpringMVC(六)——文件上传和下载
文件上传
1.需要导包
commons-fileupload
commons-io
2.请求方法的参数
MultipartFile类,全称org.springframework.web.multipart.MultipartFile。主要方法有

3.在springmvc-config.xml配置文件上传解析器
<!-- 文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
</bean>还有其他属性可以设置,例如maxUploadSize表示上传文件的最大值等。
4.通过jsp的表单提交请求
(1)method设置为post
(2)enctype设置为multipart/form-data,浏览器会采用二进制流的方式处理表单数据,服务器端会对文件上传的请求进行解析处理。
(3)<input type="file" name="filename" />
测试用的jsp例子
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; 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;
}
if(file.length==0||file==""){
alert("请选择上传文件");
return false;
}
return true;
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath }/testup"
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" /><br />
<input type="submit" value="上传" />
</form>
</body>
</html>5.控制器类
@Controller
public class FileController {
@RequestMapping("/testup")
public String testUp(@RequestParam("name")String name,@RequestParam("uploadfile") List<MultipartFile> uploadfile,HttpServletRequest request ) {
if(!uploadfile.isEmpty() && uploadfile.size()>0) {
for(MultipartFile file:uploadfile) {
String originalFilename=file.getOriginalFilename();//获取上传文件的原始名字
String dirPath=request.getServletContext().getRealPath("/upload/");//设置上传文件的保存地址目录
File filePath=new File(dirPath);
if(!filePath.exists()) {//如果保存文件的地址不存在,就先创建目录
filePath.mkdirs();
}
String newname=name+"_"+UUID.randomUUID()+"_"+originalFilename;//用UUID重新命名,这是通用唯一识别码
System.out.println("name="+name);
System.out.println("originalFilename="+originalFilename);
System.out.println("dirPath="+dirPath);
System.out.println("newname="+newname);
try {//使用MultipartFile接口的方法完成文件上传到指定位置
file.transferTo(new File(dirPath + newname));
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}
System.out.println("will return success");
return "success";
}else
return "error";
}
@RequestMapping("/up")
public String upjsp() {//通过MVC_03/up进入初始页面
return "up";
}
}这里的文件上传到workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\MVC_03\upload。
文件下载
1.导包
2.客户端页面要有一个超链接
<a href="${pageContext.request.contextPath }/download?filename=1.jpg">文件下载 </a>需要先存在1.jpg这个文件,复制粘贴也好,文件上传进去的也好。
3.控制器类写一个方法下载文件(下面代码会有中文乱码问题)
@RequestMapping("/download")
public ResponseEntity<byte[]> testDown(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);return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}指定要下载名为filename的文件,HttpStatus.OK(200)表示协议状态,服务器已经成功处理请求。不能用Byte[],亦不解。
4.解决中文乱码问题
(1)在前端页面对编码统一,中文转UTF-8
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>下载页面</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/download?filename=<%=URLEncoder.encode("壁纸.jpg", "UTF-8")%>">
中文名称文件下载
</a>
</body>
</html>第3行的URLEncoder是Servlet API提供的类。
第13行的encode(String s,String enc)方法是将前者的中文名转化为后者UTF-8编码。这里是先提供了一个壁纸.jpg的文件。
(2)后台控制器再把UTF-8转中文
//UTF-8转中文,写死的模板方法
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");
}
@RequestMapping("/download")
public ResponseEntity<byte[]> testDown(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);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
}