欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用JSP+servlet实现文件的上传与下载

程序员文章站 2022-04-14 10:14:05
用jsp+servlet实现文件的上传与下载,现在看来使用jsp+servlet实现文件的上传与下载已经是有些落后了,现在能很方便实现文件的上传与下载插件和工具有很多,常用的有smartupload...

用jsp+servlet实现文件的上传与下载,现在看来使用jsp+servlet实现文件的上传与下载已经是有些落后了,现在能很方便实现文件的上传与下载插件和工具有很多,常用的有smartupload插件、struts2框架以及富文本编辑器等等。但是作为一个合格的程序员,我认为还是有必要了解一下使用jsp+servlet最原始的读取文件流来实现文件的上传与下载。下面我简单讲下!

要使用jsp通过表单实现文件的上传与下载,首先就必须要了解enctye这个属性,enctype 属性是规定在发送到服务器之前应该如何对表单数据进行编码。enctype常用的属性值有3个:第一个是application/x-www-form-urlencoded,这是默认的编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成url编码方式,第二种是multipart/form-data,这种编码方式的表单会以二进制流的方式来处理表单数据,同时,这种编码方式也会把文件域指定文件的内容封装到请求参数里,第三种就是text/plain,这种方式主要适合用于直接通过表单发送邮件的方式。

我们要使用jsp实现文件的上传和下载,这里的enctype属性的属性值一定要选multipart/form-data,让表单提交的数据以二进制编码的方式提交,在接收此请求的servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。

下面写个小例子:

先贴出前台页面代码:

<!doctype html >
<html>
<head>
<meta charset="utf-8">
<title>使用jsp+servlet实现文件的上传下载</title>
</head>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<body>
    <h2>使用jsp+servlet实现文件的上传下载</h2>
    <form action="uploadservlet" method="post" enctype="multipart/form-data" >
            请选择文件:<input id="file" name="file" type="file" />
        <input type="submit" value="上传"  />${result}
        </form>
    下载:<a href="downloadservlet?filename=filetest.txt">filetest.txt</a> ${errorresult} 
</body>
</html>

这里一定要注意,表单的method一定要使用post方式,其它的就很简单了,至于${result}这种语句是el表达式。实现上传文件的uploadservlet的代码:

package com.dw.servlet;

import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.randomaccessfile;
import javax.servlet.requestdispatcher;
import javax.servlet.servletexception;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

public class uploadservlet extends httpservlet {
	private static final long serialversionuid = 1l;
    public uploadservlet() {
        super();
    }

	protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
		dopost(request,response);
	}

	protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
		request.setcharacterencoding("utf-8");
		response.setcharacterencoding("utf-8");
		response.setcontenttype("text/html;charset=utf-8");//更改响应字符流使用的编码,还能告知浏览器用什么编码进行显示
		
		//从request中获取文本输入流信息
		inputstream filesourcestream = request.getinputstream();
		string tempfilename = "f:/tempfile";

		//设置临时文件,保存待上传的文本输入流
		file tempfile = new file(tempfilename);
		
		//outputstram文件输出流指向这个tempfile
		fileoutputstream outputstream = new fileoutputstream(tempfile);
		
		//读取文件流
		byte temp[] = new byte[1024];
		int n;
		while(( n = filesourcestream.read(temp)) != -1){
			outputstream.write(temp, 0, n);
		}
		outputstream.close();
		filesourcestream.close();
		
		//获取上传文件的名称 
		randomaccessfile randomfile = new randomaccessfile(tempfile,"r");
		randomfile.readline();  
		string str = randomfile.readline();
		int start = str.lastindexof("=") + 2;
		int end = str.lastindexof("\"");
		string filename = str.substring(start, end);
		
		//定位文件指针到文件头
		randomfile.seek(0);
		long startindex = 0;
		int i = 1;
		//获取文件内容的开始位置
		while(( n = randomfile.readbyte()) != -1 && i <=4){
			if(n == '\n'){
				startindex = randomfile.getfilepointer();
				i ++;
			}
		}
		startindex = startindex -1; //这里一定要减1,因为前面多读了一个,这里很容易忽略
		//获取文件内容结束位置
		randomfile.seek(randomfile.length());
		long endindex = randomfile.getfilepointer();
		int j = 1;
		while(endindex >=0 && j<=2){
			endindex--;
			randomfile.seek(endindex);
			if(randomfile.readbyte() == '\n'){
				j++;
			}
		}
		
		//设置保存上传文件的路径
		string realpath =  "f:/file";
		file fileupload = new file(realpath);
		if(!fileupload.exists()){
			fileupload.mkdir();
		}
		file savefile = new file(realpath,filename);
		randomaccessfile randomaccessfile = new randomaccessfile(savefile,"rw");
		//根据起止位置从临时文件中读取文件内容
		randomfile.seek(startindex);
		while(startindex < endindex){
			randomaccessfile.write(randomfile.readbyte());
			startindex = randomfile.getfilepointer();
		}
		//关闭输入输出流并 删除临时文件
		randomaccessfile.close();
		randomfile.close();
		tempfile.delete();
		
		request.setattribute("result", "文件上传成功");
		requestdispatcher dispatcher = request.getrequestdispatcher("index.jsp");
		dispatcher.forward(request, response);
	}

}
在这个uploadservlet处理文件中,代码其实也很简单,就是处理接收到的数据流,具体步骤我在代码中注释的很清楚,一步一步来,很容易实现文件的上传,需要特别注意的是,上传的文件浏览器是使用什么的格式显示以及暂存我们的文件的。如下图:
用JSP+servlet实现文件的上传与下载
这个格式是固定不变的,不要忽略其中的空行,所以说截取文件名以及截取文件内容的时候,一定要注意截取的位置,完成到这里,我们就可以实现上传文件了!
用JSP+servlet实现文件的上传与下载用JSP+servlet实现文件的上传与下载
点击浏览后选择testfile.txt文件,点击上传,会提示上传文件成功!会在指定的存储目录下看到这个文件。


下面再说说文件下载:
文件下载原理分为三步:第一步需要通过httpservletresponse.setcontenttype方法设置响应类型content- type头字段的值,让浏览器无法使用某种方式或激活某个程序来处理的mime类型,我们这里用到的值为application/x- msdownload。第二步需要通过httpservletresponse.setheader方法设置响应头content- disposition的值为"attachment;filename=文件名"。第三步是读取文件进行下载,需要调用 httpservletrespnse.getoutputstream方法返回的servletoutputstream对象来向客服端写入附件文件的内容。

实现下载文件downloadservlet的源代码:
package com.dw.servlet;

import java.io.file;
import java.io.fileinputstream;
import java.io.ioexception;
import java.io.inputstream;
import javax.servlet.requestdispatcher;
import javax.servlet.servletexception;
import javax.servlet.servletoutputstream;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
public class downloadservlet extends httpservlet {
	private static final long serialversionuid = 1l;
    public downloadservlet() {
        super();
    }

	protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
		request.setcharacterencoding("utf-8");
		response.setcharacterencoding("utf-8");
		
		//获取文件下载路径
		string path = "f:/file/";
		string filename = request.getparameter("filename");
		file file = new file(path + filename);
		if(file.exists()){
			//设置相应类型让浏览器知道用什么打开  用application/octet-stream也可以,看是什么浏览器
			response.setcontenttype("application/x-msdownload");
			//设置头信息
			response.setheader("content-disposition", "attachment;filename=\"" + filename + "\"");
			inputstream inputstream = new fileinputstream(file);
			servletoutputstream ouputstream = response.getoutputstream();
			byte b[] = new byte[1024];
			int n ;
			while((n = inputstream.read(b)) != -1){
				ouputstream.write(b,0,n);
			}
			//关闭流
			ouputstream.close();
			inputstream.close();
		}else{
			request.setattribute("errorresult", "文件不存在,下载失败!");
			requestdispatcher dispatcher = request.getrequestdispatcher("index.jsp");
			dispatcher.forward(request, response);
		}
	}

	protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
		doget(request,response);
	}

}
当我们点击下载按钮是,会弹出下载框,如下图:
用JSP+servlet实现文件的上传与下载
点击保存文件,就可以保存文件到任意的路径,这里保存到桌面,可以看出,文件并没有出现乱码,下载成功!
用JSP+servlet实现文件的上传与下载


下面贴出web.xml文件:
用JSP+servlet实现文件的上传与下载




好了,就先讲到这里!