java中的文件上传和下载及上传组件的使用

文件上传下载原理

在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。

但是在jsp编程中不能使用FTP方法来上传文件,这是由jsp运行机制决定的。


通过为表单元素设置Method="post" enctype="multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。



表单enctype属性

application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。

multipart/form-date:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。

text/plain:这种方式主要适用于直接通过表单发送邮件的方式。






Jsp+Servlet实现文件上传下载

前台页面:
<link rel="stylesheet" type="text/css" href="css/common.css" />
	<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
	<script type="text/javascript">
		$(function(){
			$(".thumbs a").click(function(){
				var largePath  = $(this).attr("href");
				var largeAlt = $(this).attr("title");
				$("#largeImg").attr({
					src : largePath,
					alt : largeAlt
				});
				return false;
			});
			
			//实现预览即将上传的图片的功能
			$("#myfile").change(function(){
				 var file = this.files[0];
	                var reader = new FileReader();
	                reader.readAsDataURL(file);
	                reader.onload = function(e){
	                    $("#previewImg").attr("src", e.target.result);
	                };
			});
			
			var la = $("#large");
			la.hide();
			
			$("#previewImg").mousemove(function(e){
				la.css({
					top : e.pageY,
					left : e.pageX
				}).html('<img src = "' + this.src + '" />').show();
			}).mouseout(function(){
				la.hide();
			});
		});	
		
	</script>
  </head>
  
  <body>

  	 <img id="previewImg" src="images/preview.jpg" width="80" height="80" />
  	 <form action="upload" method="post" enctype="multipart/form-data"> 
  		请选择图片:<input id="myfile" name="myfile" type="file" />
  		<input type="submit" value="提交"  />${result} 
  	</form>
  	
  	下载:<a href="download?filename=test.txt">test.txt</a>    ${errorResult}
  	
  	<div id="large"></div>
  	
  	<hr>
    <h2>图片预览</h2>
    <p><img id="largeImg" src="images/img1-lg.jpg" alt="Large Image"/></p>
    <p class="thumbs">
    	<a href="images/img2-lg.jpg" title="Image2"><img src="images/img2-thumb.jpg"></a>
    	<a href="images/img3-lg.jpg" title="Image3"><img src="images/img3-thumb.jpg"></a>
    	<a href="images/img4-lg.jpg" title="Image4"><img src="images/img4-thumb.jpg"></a>
    	<a href="images/img5-lg.jpg" title="Image5"><img src="images/img5-thumb.jpg"></a>
    	<a href="images/img6-lg.jpg" title="Image6"><img src="images/img6-thumb.jpg"></a>
    </p>
利用Jquery实现了上传图片的预览以及图片缩略图的浏览


上传Servlet:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//从req中获取流信息
		InputStream fileSource = req.getInputStream();
		String tempFileName="F:/eclipse_workspace/UploadAndDownload/tempFile";
		File tempfile = new File(tempFileName);
		//文件输出流指向临时文件
		FileOutputStream fileOutputStream = new FileOutputStream(tempfile);
		byte[] b=new byte[1024];
		int n;
		while((n=fileSource.read(b))!=-1){
			fileOutputStream.write(b, 0, n);
		}
		
		fileOutputStream.close();
		fileSource.close();
		
		//获取上传文件的名称
		RandomAccessFile randomFile=new RandomAccessFile(tempfile,"r");
		randomFile.readLine();
		String str=randomFile.readLine();
		int beginIndex=str.lastIndexOf("=")+2;
		int endIndex=str.lastIndexOf("\"");
		
		String filename=str.substring(beginIndex,endIndex);
		System.out.println("filename:"+filename);
		
		//重新定位文件指针到文件头
		randomFile.seek(0);
		long startPosition = 0;
		int i = 1;
		//获取文件内容 开始位置
		while(( n = randomFile.readByte()) != -1 && i <=4){
			if(n == '\n'){
				startPosition = randomFile.getFilePointer();
				i ++;
			}
		}
		startPosition = randomFile.getFilePointer() -1;
		//获取文件内容 结束位置
		randomFile.seek(randomFile.length());
		long endPosition = randomFile.getFilePointer();
		int j = 1;
		while(endPosition >=0 && j<=2){
			endPosition--;
			randomFile.seek(endPosition);
			if(randomFile.readByte() == '\n'){
				j++;
			}
		}
		endPosition = endPosition -1;
		
		
		//设置保存上传文件的路径
		String realPath = getServletContext().getRealPath("/") + "images";
		File fileupload = new File(realPath);
		if(!fileupload.exists()){
			fileupload.mkdir();
		}
		File saveFile = new File(realPath,filename);
		RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw");
		//从临时文件当中读取文件内容(根据起止位置获取)
		randomFile.seek(startPosition);
		while(startPosition < endPosition){
			randomAccessFile.write(randomFile.readByte());
			startPosition = randomFile.getFilePointer();
		}
		//关闭输入输出流、删除临时文件
		randomAccessFile.close();
		randomFile.close();
		tempfile.delete();
				
		req.setAttribute("result", "上传成功!");
		RequestDispatcher dispatcher = req.getRequestDispatcher("jsp/01.jsp");
		dispatcher.forward(req, resp);
	}


单个文件下载Servlet:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//获取文件下载路径
		String path = getServletContext().getRealPath("/") + "images/";
		String filename = req.getParameter("filename");
		File file = new File(path + filename);
		if(file.exists()){
			//设置相应类型application/octet-stream
			resp.setContentType("application/x-msdownload");
		    //设置头信息
			resp.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
		    InputStream inputStream = new FileInputStream(file);
			ServletOutputStream ouputStream = resp.getOutputStream();
			byte b[] = new byte[1024];
			int n ;
			while((n = inputStream.read(b)) != -1){
				ouputStream.write(b,0,n);
			}
			//关闭流、释放资源
			ouputStream.close();
			inputStream.close();
					
					
		}else{
			req.setAttribute("errorResult", "文件不存在下载失败!");
			RequestDispatcher dispatcher = req.getRequestDispatcher("jsp/01.jsp");
			dispatcher.forward(req, resp);
		}
				
	}




批量下载BatchDownloadServlet.java:

public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType("application/x-msdownload");
		resp.setHeader("Content-Disposition", "attachment;filename=test.zip");
		String path = getServletContext().getRealPath("/") + "images/";
		String[] filenames  = req.getParameterValues("filename");
		String str = "";
		String rt = "\r\n";
		ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream());
		for(String filename : filenames){
			str += filename + rt;
			File file = new File(path + filename);
			zos.putNextEntry(new ZipEntry(filename));
			FileInputStream fis = new FileInputStream(file);
			byte b[] = new byte[1024];
			int n = 0;
			while((n = fis.read(b)) != -1){
				zos.write(b, 0, n);
			}
			zos.flush();
			fis.close();
		}
		zos.setComment("download success:" + rt + str);
		zos.flush();
		zos.close();
		
	}

将请求下载的所有文件打包成zip下载到客户端

亲测有效!!






应用SmartUpload实现上传下载

在实际开发中我们都是使用组件/框架实现文件的上传下载

SmartUpload介绍

SmartUpload是由www.jspsmart.com网站开发的一套上传组件包,可以轻松实现文件的上传下载
使用该组件可以轻松实现上传文件类型的限制也可以轻易取得上传文件的名称、后缀、大小等

SmartUpload本身也是系统提供的一个Jar包,直接将此包放到classpath下即可,也可以拷贝到TOMCAT_HOME/lib目录下



前台页面02.jsp:
 <body>
	<h2>文件批量上传	</h2>
  	<form action="batch-upload" method="post" enctype="multipart/form-data">
  		上传文件1:<input type="file" name="myfile1"><br>
  		上传文件2:<input type="file" name="myfile2"><br>
  		上传文件3:<input type="file" name="myfile3"><br>
  		<input type="submit" value="提交">${result}
  	</form>
  	<hr>
  	
  	
  	 下载:<a href="smart-download?filename=img2-lg.jpg">img2-lg.jpg</a> 
  	 
  	 
  	 <h2>文件批量下载</h2>
  	 <form action="batch-download">
  	 	<input type="checkbox"  name="filename" value="img2-lg.jpg">Image2
  	 	<input type="checkbox"  name="filename" value="img3-lg.jpg">Image3
  	 	<input type="checkbox"  name="filename" value="img4-lg.jpg">Image4
  	 	<input type="submit" value="下载">
  	 </form> 
  	<hr>
    <h2>图片预览</h2>
    <p><img id="largeImg" src="images/img1-lg.jpg" alt="Large Image"/></p>
    <p class="thumbs">
    	<a href="images/img2-lg.jpg" title="Image2"><img src="images/img2-thumb.jpg"></a>
    	<a href="images/img3-lg.jpg" title="Image3"><img src="images/img3-thumb.jpg"></a>
    	<a href="images/img4-lg.jpg" title="Image4"><img src="images/img4-thumb.jpg"></a>
    	<a href="images/img5-lg.jpg" title="Image5"><img src="images/img5-thumb.jpg"></a>
    	<a href="images/img6-lg.jpg" title="Image6"><img src="images/img6-thumb.jpg"></a>
    </p>
  </body>




批量上传SmartUploadServlet.java:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//设置上传文件保存路径
		String filePath = getServletContext().getRealPath("/") + "images";
		File file = new File(filePath);
		if(!file.exists()){
			file.mkdir();
		}
				
		SmartUpload su = new SmartUpload();
		//初始化对象
		su.initialize(getServletConfig(), req, resp);
		//设置上传文件大小上限10M
		su.setMaxFileSize(1024*1024*10);  
		//设置所有文件的大小上限
		su.setTotalMaxFileSize(1024*1024*100);
		//设置允许上传文件类型
		su.setAllowedFilesList("txt,jpg,gif");
		String result = "上传成功!";
		//设置禁止上传的文件类型
		try {
			su.setDeniedFilesList("rar,jsp,js");
			//上传文件
			su.upload();
			//保存文件个数		
			int count = su.save(filePath);
			System.out.println("上传成功" +  count + "个文件!");
		} catch (Exception e) {
			result = "上传失败!";
			if(e.getMessage().indexOf("1015")!=-1){
				result = "上传失败:上传文件类型不正确!";
			}else if(e.getMessage().indexOf("1010")!=-1){
				result = "上传失败:上传文件类型不正确!";
			}else if(e.getMessage().indexOf("1105")!=-1){
				result = "上传失败:上传文件大小大于上限!";
			}else if(e.getMessage().indexOf("1110")!=-1){
				result = "上传失败:上传文件总大小大于总大小上限!";
			}
			e.printStackTrace();
		}
				
		for(int i =0; i < su.getFiles().getCount(); i++){
			com.jspsmart.upload.File tempFile = su.getFiles().getFile(i);
			System.out.println("---------------------------");
			System.out.println("表单当中name属性值:" + tempFile.getFieldName());
			System.out.println("上传文件名:" + tempFile.getFileName());
			System.out.println("上传文件长度:" + tempFile.getSize());
			System.out.println("上传文件的拓展名:" + tempFile.getFileExt());
			System.out.println("上传文件的全名:" + tempFile.getFilePathName());
			System.out.println("---------------------------");
		}
				
		req.setAttribute("result", result);
		req.getRequestDispatcher("jsp/02.jsp").forward(req, resp);
	}




单个文件下载SmartDownloadServlet.java

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String filename = request.getParameter("filename");
		
		SmartUpload su = new SmartUpload();
		su.initialize(getServletConfig(), request, response);
		//不使用默认的下载方式
		su.setContentDisposition(null);
		try {
			su.downloadFile("/images/"+ filename);
		} catch (SmartUploadException e) {
			e.printStackTrace();
		}
	}






SmartUpload与commons-fileupload对比

SmartUpload:

优点:使用简单,可以轻松实现文件上传类型的限制,轻易取得上传文件的名称、后缀、大小等
缺点:上传大文件或者多文件的时候可能出现CPU或内存占用过高的问题



因为以上缺点,因此现在用的比较多的还是commons-fileupload


commons-fileupload:

主流框架(struts2,springmvc)均使用commons-fileupload,需要结合commons-io.jar,对中文有很好的支持,性能高于SmartUpload






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值