SpringMVC 文件上传及下载
文件下载
inline
访问资源时如果没有设置响应头Content-Disposition,浏览器默认按照inline进行处理
inline:能显示就显示,不能显示就下载
响应头
只需修改响应头Content-Disposition=“attachment;filename=文件名”
attachment表示下载,以附件形式下载
filename表示下载时,下载的文件名
实现步骤
①jsp中添加超链接,设置要下载的文件
Ps:超链接实质是传输到服务器一个文件名,而这个文件一定是存在的,也可以使用一个输入框,输入要下载的文件名,然后查询该文件是否存在,以此来实现选择指定的文件来下载。
②控制器定义方法为void类型,参数使用filename(接收文件名),HttpServletResponse res(定位文件位置),HttpServletRequest req(转发资源)
③使用res设置响应头:
res.setContentType(" “)或res.setHeader(“Content-Disposition”,” ")
④使用res获取字节输出流:res.getOutputStream()
⑤使用req获取到文件路径:req.getServletContext().getRealPath(“files”)+"/"+fileName
⑥再将文件转为byte数组(可使用Commons-IO,也可通过ByteArrayInputStream进行转换),通过res获取到的流输出并刷新。
具体实现
超链接:
<a href="/SpringMVCTest/download?filename=Test.zip">下载文件</a>
控制器:
@RequestMapping("/download")
public void download(String filename,HttpServletResponse res,HttpServletRequest req) {
//获取到文件路径(此处不知为何将files放入参数中会找不到)
String path = req.getServletContext().getRealPath("")+"files";
try {
byte data[] = FileUtils.readFileToByteArray(new File(path,filename));
//修改响应头
//res.setContentType("attachment;filename="+filename);
res.setHeader("Content-Disposition", "attachment;filename="+filename);
//获取输出流
OutputStream oStream = res.getOutputStream();
oStream.write(data);
oStream.flush();
oStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
测试结果
文件位置:
下载页面:
文件上传
基于apache的commons-fileupload.jar完成文件上传
MultipartResolver(组件)
①将客户端上传的文件流转换为MutipartFile封装类
②通过MutipartFile封装类获取到文件流
jsp页面
通过<form>的enctype属性来控制表单类型,
value | purpose |
---|---|
application/x-www-form-urlencoded | 少量文字信息(默认) |
text/plain | 表示大量文字类型(邮件、论文等) |
multipart/form-data | 表单中包含二进制文件内容(上传文件) |
通过method属性来控制访问类型:
“POST”,最大值2GB,字节流;GET,最大2K,字符流
SpringMVC配置文件
配置MultipartResolver解析器:
<bean id="" class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”/>
属性值:
maxUploadSize,文件最大上传,单位字节,超过会报异常
defaultEncoding,默认编码
实现步骤
①设置参数MultipartFile filename来获取到上传的文件(
形参名和表单中文件上传的name相同,即<input type=“file” name=“filename”>
或使用@RequestParam(“filename”)进行注入
②通过file.getOriginalFilename()来获取文件全称,再通过substring获取文件后缀(用以确认文件类型)
③通过UUID.randomUUID().toString()来获取一个唯一标识符和文件后缀进行拼接获取文件名Ps:此处可使用数据库将文件名和生成的UUID建立起key-value关系,便于下载
④通过file.getInputStream()获取输出流
⑤可通过Commons-IO将输出流输入到一个新文件中
Tips:防止别人访问,可在filter中过滤id
具体实现
jsp端表单:
<form action="/SpringMVCTest/upload" enctype="multipart/form-data" method="POST">
上传文件:<input type="file" name="file">
<input type="submit" name="提交">
</form>
SpringMVC配置文件
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大文件大小 -->
<property name="maxUploadSize" value="20480"></property>
<!-- 默认编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
控制器:
@RequestMapping("/upload")
public void upload(@RequestParam("file")MultipartFile file,ServletRequest req) {
//获取路径
String path = file.getOriginalFilename();
//获取文件后缀(类型)
String last = path.substring(path.lastIndexOf("."));
String name = UUID.randomUUID().toString()+last;
//获取上传文件的输入流
try {
InputStream iStream = file.getInputStream();
FileUtils.copyInputStreamToFile(iStream ,new File(req.getServletContext().getRealPath("")+"files",name));
iStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
测试结果
上传界面:
上传成功后存储位置: