文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver
为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="upload">
form>
设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,之前使用的commons-fileupload是Servlet/JSP程序员上传文件的最佳选择,Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。而Spring MVC则提供了更简单的封装,即直接用multipartResolver实现。
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.3version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>4.0.1version>
dependency>
bena的id必须为:multipartResolver , 否则上传文件会报400的错误
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="org.westos.controller"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
<property name="maxUploadSize" value="1048576"/>
<property name="maxInMemorySize" value="40960"/>
bean>
beans>
Tip:@RequestParam(“file”) 将name=file控件得到的文件封装成CommonsMultipartFile 对象,我们在上面的前端配置的地方将input类型为file的标签的name设置为了file,所以这里注解内也为file
实现思路:
1.首先获取上传文件的文件名
2.设置上传文件的保存路径
3.使用字节输入流和字节输出流实现文件上传
4.关闭流
@Controller
public class FileController {
//采用流的方式上传文件
@RequestMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//获得文件名
String filename = file.getOriginalFilename();
if ("".equals(filename)){
return "文件不存在";
}
//上传文件保存路径
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
//文件上传
InputStream inputStream = file.getInputStream();
FileOutputStream outputStream = new FileOutputStream(new File(realPath, filename));
int len = 0;
byte[] bytes = new byte[1024];
while ((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
outputStream.flush();
}
//关闭流
outputStream.close();
inputStream.close();
return "上传完毕";
}
}
除了使用流的方式上传文件,我们还可以使用Transto方法上传文件
@Controller
public class FileController {
//采用file.Transto上传文件
@RequestMapping("/upload2")
@ResponseBody
public String upload2(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) throws IOException {
//上传文件保存路径
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
//transferTo将文件写入磁盘,参数传入一个文件
file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));
return "上传完毕";
}
}
package org.westos.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@Controller
public class DownloadController {
@RequestMapping("/download2")
public String download(HttpServletRequest request, HttpServletResponse response) {
String fileName = "1.png";
System.out.println(fileName);
response.setContentType("text/html;charset=utf-8");
try {
request.setCharacterEncoding("UTF-8");//设定请求字符编码
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
BufferedInputStream bis = null;//创建输入输出流
BufferedOutputStream bos = null;
String realPath = request.getSession().getServletContext().getRealPath("/") + "upload/";//获取文件真实路径
System.out.println(realPath);
String downLoadPath = realPath + fileName;
System.out.println(downLoadPath);
try {
long fileLength = new File(downLoadPath).length();//获取文件长度
//设置响应头信息;【固定的不用记,保存即可】
response.setContentType("application/x-msdownload;");
response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
response.setHeader("Content-Length", String.valueOf(fileLength));
bis = new BufferedInputStream(new FileInputStream(downLoadPath));//创建输入输出流实例
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];//创建字节缓冲大小
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null)
try {
bis.close();//关闭输入流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (bos != null)
try {
bos.close();//关闭输出流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}