SpringMVC通过MultipartResolver(多部件解析器)对象实现对文件上传的支持。
MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver来完成文件的上传工作。
前端
注意事项:
1.post提交数据
2.form表单 --> enctype属性为:multipart/form-data
3.使用上传文件的file标签
导入依赖:
<!-- 将对多部分文件上传功能的支持添加到Servlet和Web应用程序 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Springmvc项目当中需要加的配置,在applicatinContext.xml中添加上传和下载的配置文件,如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 限制文件上传总大小,不设置默认没有限制,单位为字节 200*1024*1024即200M -->
<property name="maxUploadSize" value="209715200" />
<!-- 设置每个上传文件的大小上限 -->
<property name="maxUploadSizePerFile" value="1048576"/>
<!-- 处理文件名中文乱码 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
<property name="resolveLazily" value="true" />
</bean>
编写前端部分代码(注意文章开头强调内容)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
文件名<input type="file" name="photo"/><br/>
<input type="text" name="desc"/> <br/>
<input type="submit" value="提交"/><br/>
</form>
<a href="${pageContext.request.contextPath}/fileDownLoad">前去下载</a>
</body>
</html>
编写上传和下载控制器类
package com.fanlan.Controller;
.....
@Controller
public class fileController {
@RequestMapping("/upload")
public String testUpload(HttpServletRequest request, @RequestParam(value="desc",required=false) String desc
, @RequestParam("photo") CommonsMultipartFile file) throws Exception{
//获取ServletContext的对象 代表当前WEB应用
ServletContext servletContext = request.getSession().getServletContext();
//得到文件上传目的位置的真实路径
String realPath = servletContext.getRealPath("/uploads");
System.out.println("realPath :"+realPath);
File file1 = new File(realPath);
//如果该目录不存在,就创建此抽象路径名指定的目录。
if(!file1.exists()){
file1.mkdir();
}
String prefix = UUID.randomUUID().toString();
prefix = prefix.replace("-","");
String fileName = prefix+"_"+file.getOriginalFilename();//使用UUID加前缀命名文件,防止名字重复被覆盖
//声明输入输出流
InputStream in= file.getInputStream();;
//指定输出流的位置;
OutputStream out=new FileOutputStream(new File(realPath+"\\"+fileName));
//类似于文件复制,将文件存储到输入流,再通过输出流写入到上传位置
//这段代码也可以用IOUtils.copy(in, out)工具类的copy方法完成
byte []buffer =new byte[1024];
int len=0;
while((len=in.read(buffer))!=-1) {
out.write(buffer, 0, len);
out.flush();
}
//关闭流
out.close();
in.close();
//这里需要你写一个简单反馈页面
return "success";
}
@RequestMapping("/fileDownLoad")
public ResponseEntity<byte[]> fileDownLoad(HttpServletRequest request) throws Exception{
ServletContext servletContext = request.getSession().getServletContext();
String fileName="1.jpg";
//得到文件所在位置
String realPath = servletContext.getRealPath("/WEB-INF/"+fileName);
//将该文件加入到输入流之中
InputStream in=new FileInputStream(new File(realPath));
byte[] body=null;
// 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数
body=new byte[in.available()];
//读入到输入流里面
in.read(body);
//防止中文乱码
fileName=new String(fileName.getBytes("gbk"),"iso8859-1");
//设置响应头
HttpHeaders headers=new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename="+fileName);
HttpStatus statusCode = HttpStatus.OK;//设置响应吗
ResponseEntity<byte[]> response=new ResponseEntity<byte[]>(body, headers, statusCode);
return response;
//public ResponseEntity(T body,
// MultiValueMap < String,String > headers,
// HttpStatus statusCode)
//HttpEntity使用给定的正文,标题和状态代码创建一个新的。
//参数:
//body - 实体机构
//headers - 实体头
//statusCode - 状态码
}
}
注意下载操作中这块代码:
String fileName="1.jpg";
//得到文件所在位置
String realPath = servletContext.getRealPath("/WEB-INF/"+fileName);
注意点:
1.文件的提前准备
2.必定会出现资源无法导出问题👇