1. 简介
提供基于spring实现文件(笔记附件)的上传和下载的完整方案。方案将文件上传,并将文件名称作为字段与关联的笔记绑定在一起,更新笔记在数据库中的记录。显示笔记时,根据笔记所绑定的文件名生成下载路径,提交给服务端完成下载。
2. 文件上传
2. 1 前端
在html中插入一个表单用于提交文件
- <form id= "uploadForm">
- <input type="file" name="file" id="file"/>
- <input type="button" id="upload" value="上传附件"/>
- </form>
<form id= "uploadForm">
<input type="file" name="file" id="file"/>
<input type="button" id="upload" value="上传附件"/>
</form>
编写js给button单击事件,发送ajax请求,将文件数据上传给服务端,服务端返回存储的真实文件名,将文件名绑定在笔记元素上,在保存笔记时,将文件名写入相应笔记的数据库记录中。
- //给上传文件按钮绑定事件
- $("#upload").click(uploadFile);
//给上传文件按钮绑定事件
$("#upload").click(uploadFile);
- function uploadFile(){
- //获得上传文件
- $.ajax({
- url: 'file/upload.do',
- type: 'POST',
- cache: false,
- data: new FormData($('#uploadForm')[0]),
- processData: false,
- contentType: false,
- success:function(result){
- var $checkedLi = $("#note_list li a.checked").parent();
- $checkedLi.data("attachment",result.data);
- alert("上传成功"+result.data);
- }
- });
- }
function uploadFile(){
//获得上传文件
$.ajax({
url: 'file/upload.do',
type: 'POST',
cache: false,
data: new FormData($('#uploadForm')[0]),
processData: false,
contentType: false,
success:function(result){
var $checkedLi = $("#note_list li a.checked").parent();
$checkedLi.data("attachment",result.data);
alert("上传成功"+result.data);
}
});
}
1. 2 后端
采用CommonsMultipartResolver,需要导入commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar,sc是ServletContext的引用,用实现ServletContextAware接口的方式获得。
- public JsonResult upload(HttpServletRequest request,HttpServletResponse response) throws Exception{
- JsonResult result = new JsonResult();
- try{
- request.setCharacterEncoding("utf-8");
- //创建一个通用的多部分解析器
- CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(sc);
- //判断 request 是否有文件上传,即多部分请求
- if(multipartResolver.isMultipart(request)){
- //转换成多部分request
- MultipartHttpServletRequest multiRequest =
- multipartResolver.resolveMultipart(request);
- //取得request中的所有文件名
- Iterator<String> iter = multiRequest.getFileNames();
- while(iter.hasNext()){
- //取得上传文件
- MultipartFile file = multiRequest.getFile(iter.next());
- if(file != null){
- //取得当前上传文件的文件名称
- String myFileName = file.getOriginalFilename();
- //如果名称不为“”,说明该文件存在,否则说明该文件不存在
- if(myFileName.trim() !=""){
- //重命名上传后的文件名
- String fileName = file.getOriginalFilename();
- //定义上传路径
- String dirPath = sc.getRealPath("/WEB-INF/files/");
- File dir = new File(dirPath);
- if(!dir.exists()){
- dir.mkdirs();
- }
- File localFile = new File(dir, NoteUtil.creatId().substring(30)+"-"+fileName);
- file.transferTo(localFile);
- //结果绑定文件路径
- result.setStatus(0);
- result.setData(localFile.getName());
- result.setMsg("上传成功");
- }
- }
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- throw e;
- }
- result.setStatus(1);
- return result;
- }
public JsonResult upload(HttpServletRequest request,HttpServletResponse response) throws Exception{
JsonResult result = new JsonResult();
try{
request.setCharacterEncoding("utf-8");
//创建一个通用的多部分解析器
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(sc);
//判断 request 是否有文件上传,即多部分请求
if(multipartResolver.isMultipart(request)){
//转换成多部分request
MultipartHttpServletRequest multiRequest =
multipartResolver.resolveMultipart(request);
//取得request中的所有文件名
Iterator<String> iter = multiRequest.getFileNames();
while(iter.hasNext()){
//取得上传文件
MultipartFile file = multiRequest.getFile(iter.next());
if(file != null){
//取得当前上传文件的文件名称
String myFileName = file.getOriginalFilename();
//如果名称不为“”,说明该文件存在,否则说明该文件不存在
if(myFileName.trim() !=""){
//重命名上传后的文件名
String fileName = file.getOriginalFilename();
//定义上传路径
String dirPath = sc.getRealPath("/WEB-INF/files/");
File dir = new File(dirPath);
if(!dir.exists()){
dir.mkdirs();
}
File localFile = new File(dir, NoteUtil.creatId().substring(30)+"-"+fileName);
file.transferTo(localFile);
//结果绑定文件路径
result.setStatus(0);
result.setData(localFile.getName());
result.setMsg("上传成功");
}
}
}
}
}catch(Exception e){
e.printStackTrace();
throw e;
}
result.setStatus(1);
return result;
}
2. 文件下载
2. 1 前端
由于get请求存在中文编码异常的问题,所以采用post请求,首先获取元素中绑定的文件名,生成一个表单
- if(attachment!=null){
- var form_str = '<form action="file/download.do" method="post">'+
- '<input type="hidden" name="fileName" value="'+attachment+'"></input>'+
- '<input type="submit" value="下载附件"></input>'+
- '</form>';
- $("#download_attachment").html(form_str);
- }
if(attachment!=null){
var form_str = '<form action="file/download.do" method="post">'+
'<input type="hidden" name="fileName" value="'+attachment+'"></input>'+
'<input type="submit" value="下载附件"></input>'+
'</form>';
$("#download_attachment").html(form_str);
}
2. 2 后端
后端需要解决中文文件名无法正常显示的问题,采用ISO8859-1字符集
- public void download(HttpServletResponse response, String fileName) throws Exception{
- System.out.println(fileName);
- String filePath = "/WEB-INF/files/"+fileName;
- String fileFullPath = sc.getRealPath(filePath);
- File file = new File(fileFullPath);
- if(file.exists()){
- //重置response
- response.reset();
- response.setCharacterEncoding("utf-8");
- response.setContentType("text/html;charset=utf-8");
- //设置http头信息的内容
- / response.addHeader("Content-Disposition", "attachment;filename=\""+fileName+"\"");
- //解决中文文件名显示问题
- response.addHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"),"ISO8859-1"));
- //设置文件长度
- int fileLength = (int)file.length();
- response.setContentLength(fileLength);
- if(fileLength!=0){
- InputStream inStream = new FileInputStream(file);
- byte[] buf = new byte[4096];
- //创建输出流
- ServletOutputStream servletOS = response.getOutputStream();
- int readLength;
- //读取文件内容并写入到response的输出流当中
- while((readLength = inStream.read(buf))!=-1){
- servletOS.write(buf, 0, readLength);
- }
- //关闭输入流
- inStream.close();
- //刷新输出流缓冲
- servletOS.flush();
- //关闭输出流
- servletOS.close();
- }
- }else{
- response.setContentType("text/html;charset=utf-8");
- PrintWriter out = response.getWriter();
- out.println("文件\""+fileName + "\"不存在");
- }
- }