spring实现文件上传和下载 完整方案

5 篇文章 0 订阅

1. 简介

提供基于spring实现文件(笔记附件)的上传和下载的完整方案。方案将文件上传,并将文件名称作为字段与关联的笔记绑定在一起,更新笔记在数据库中的记录。显示笔记时,根据笔记所绑定的文件名生成下载路径,提交给服务端完成下载。

2. 文件上传

2. 1 前端

在html中插入一个表单用于提交文件
<form id= "uploadForm">
	<input type="file" name="file" id="file"/>
        <input type="button" id="upload" value="上传附件"/>
</form>

编写js给button单击事件,发送ajax请求,将文件数据上传给服务端,服务端返回存储的真实文件名,将文件名绑定在笔记元素上,在保存笔记时,将文件名写入相应笔记的数据库记录中。
//给上传文件按钮绑定事件
			$("#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);
			    }
			});	
		}

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;
	}

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);
			}

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 + "\"不存在");
		}
	}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值