目录
1. 文件上传
文件上传也属于客户端把数据发送到服务器,服务器端接收客户端的数据,但这个时候服务端接收客户端请求数据,它就是不是一个普通数据,可能是一个文件。
文件上传原理
- 当form表单修改为多部分表单时,request.getParameter()将失效。
- 包括getParameterMap()这些都会失效,因为这个request在get某某方法时,它其实获得的是url编码方式的表单提交,而文件上传的是多部分表单形势,所以这些api都失效了
- enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是:key=value&key=value&key=value
- 当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:
(右边就是他的请求正文,name 是普通表单项,file是文件上传项,通过抓包可以发file就是不是键值对形式的了。那么服务端可以获取你表单上的所有信息,包括文件名称,文件的所有内容等等)
1. 文件上传客户端三要素
●c 表单项type=“file”
● 表单的提交方式是post
● 表单的enctype属性是多部分表单形式,及entype=“multipart/form-data”
单文件上传
- 添加文件上传相关依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
- 在springMVC核心配置文件中配置文件上传解析器(CommonsMultipartResolver)
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 文件最大大小(字节) 1024*1024*50=50M-->
<property name="maxUploadSize" value="52428800"></property>
<!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
<property name="resolveLazily" value="true"/>
</bean>
- 编写文件上传代码
在这里文件上传中,SpringMVC把文件上传的文件封装成了一个对象,这个对象叫做MultipartFile,那么MultipartFile这个类型的名字要跟你当前你文件上传表单中的file的名字一致,就是那个name属性的值
<form action="${ctx}/bookFile/upload" method="post" enctype="multipart/form-data">
<label>书本编号:</label><input type="text" name="bookId" value="${param.bookId}" readonly="readonly"><br>
<label>书本图片1:</label><input type="file" name="bfile" value=""><br>
<input type="submit" value="上传">
</form>
在这我命名为bfile
后端:
private static final String DEAULT_PATH="/uploads/";
/**
* 文件上传
* @return
*/
@RequestMapping("/upload")
public String upload(MultipartFile bfile,HttpServletRequest request){
try{
//获取文件名
String Filename = bfile.getOriginalFilename();
//获取图片路径
String path=DEAULT_PATH+Filename;
//获取保存图片的绝地路径
String filePath = transfor(path, request);
//将上传的图片保存到指定位置(读流写流)
bfile.transferTo(new File(filePath));
}catch (Exception e){
e.printStackTrace();
}
return "redirect:/book/queryBookPage";
}
/**
* 将相对路径转为绝对路径
* @param relativePath
* @return
*/
private String transfor(String relativePath, HttpServletRequest request){
return request.getServletContext().getRealPath(relativePath);
}
启动服务器运行,发现bfile对象是有值的,说明文件上传成功了
测试
图片保存位置:
多文件上传
多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可
前端: 加上multiple就可以实现多文件选项
<input type="file" id="upload" name="file" multiple/> <br />
后端:
/**
* 文件上传
* @return
*/
@RequestMapping("/upload")
public String upload(MultipartFile[] bfile,HttpServletRequest request){
try{
for (MultipartFile bfile : bfiles) {
//获取文件名
String Filename = bfile.getOriginalFilename();
//获取图片路径
String path=DEAULT_PATH+Filename;
//获取保存图片的绝地路径
String filePath = transfor(path, request);
//将上传的图片保存到指定位置(读流写流)
bfile.transferTo(new File(filePath));
}
}catch (Exception e){
e.printStackTrace();
}
return "redirect:/book/queryBookPage";
}
测试:
图片保存位置:
文件下载
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(@RequestParam String fileId, HttpServletRequest request){
try{
//先根据文件id查询对应图片信息
BookFile bookFile = bookFileService.selectByPrimaryKey(fileId);
//数据库中图片的相对路径转换成绝对路径
String transfor = transfor(bookFile.getUrl(), request);
//下载关键代码
File file=new File(transfor);
//http头信息
HttpHeaders headers = new HttpHeaders();
String downloadFileName = new String(bookFile.getRealName().getBytes("UTF-8"),"iso-8859-1");//设置编码
headers.setContentDispositionFormData("attachment", downloadFileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
至此, SpringMVC文件上传介绍完毕,在此你还可以与struts2的文件上传对比。
由于作者水平有限难免有疏漏,欢迎留言纠错。