Java Web端程序实现文件下载的方法分享
Web文件下载有两种,一种是文件在网站目录下,在浏览器中直接输入文件路径即可下载,如http://www.xxx.com/file.zip。另外一种是文件不在网站目录下或者文件是动态生成的(导出报表或者导出excel等),这种情况需要通过response的OutputStream实现文件的下载。DownloadUtils是一个JavaWeb文件下载工具类,提供多种静态方法实现文件下载。
packagecom.rhui.util;
importjava.io.BufferedInputStream;
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.net.URLEncoder;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.commons.lang3.StringUtils;
/**
*文件下载类
*/
publicclassDownloadUtils{
/**
*文件下载编码
*该编码告诉浏览器文件名的编码方式,以防下载中文文件名时有乱码
*/
privatestaticStringencoding="utf-8";
/**
*文件下载
*@paramresponse
*@paramfilePath文件在服务器上的路径,包含文件名
*/
publicstaticvoiddownload(HttpServletResponseresponse,StringfilePath){
Filefile=newFile(filePath.toString());
download(response,file,null,encoding);
}
/**
*文件下载
*@paramresponse
*@paramfilePath文件在服务器上的路径,包括文件名称
*@paramfileName文件下载到浏览器的名称,如果不想让浏览器下载的文件名称和服务器上的文件名称一样,请设置该参数
*/
publicstaticvoiddownload(HttpServletResponseresponse,StringfilePath,StringfileName){
Filefile=newFile(filePath.toString());
download(response,file,fileName,encoding);
}
/**
*文件下载
*@paramresponse
*@paramfilePath文件在服务器上的路径,包括文件名称
*@paramfileName文件下载到浏览器的名称,如果不想让浏览器下载的文件名称和服务器上的文件名称一样,请设置该参数
*@paramencoding文件名称编码
*/
publicstaticvoiddownload(HttpServletResponseresponse,StringfilePath,StringfileName,Stringencoding){
Filefile=newFile(filePath.toString());
download(response,file,fileName,encoding);
}
/**
*文件下载
*@paramresponse
*@paramfile文件
*@paramfileName文件下载到浏览器的名称,如果不想让浏览器下载的文件名称和服务器上的文件名称一样,请设置该参数
*/
publicstaticvoiddownload(HttpServletResponseresponse,Filefile){
download(response,file,null,encoding);
}
/**
*文件下载
*@paramresponse
*@paramfile文件
*@paramfileName文件下载到浏览器的名称,如果不想让浏览器下载的文件名称和服务器上的文件名称一样,请设置该参数
*/
publicstaticvoiddownload(HttpServletResponseresponse,Filefile,StringfileName){
download(response,file,fileName,encoding);
}
/**
*文件下载
*@paramresponse
*@paramfile文件
*@paramfileName文件下载到浏览器的名称,如果不想让浏览器下载的文件名称和服务器上的文件名称一样,请设置该参数
*@paramencoding文件名称编码
*/
publicstaticvoiddownload(HttpServletResponseresponse,Filefile,StringfileName,Stringencoding){
if(file==null||!file.exists()||file.isDirectory()){
return;
}
//如果不指定文件下载到浏览器的名称,则使用文件的默认名称
if(StringUtils.isBlank(fileName)){
fileName=file.getName();
}
try{
InputStreamis=newFileInputStream(file);
download(response,is,fileName,encoding);
}catch(IOExceptione){
e.printStackTrace();
}
}
/**
*文件下载
*@paramresponse
*@paramis文件输入流
*@paramfileName下载的文件名称
*@throwsIOException
*/
publicstaticvoiddownload(HttpServletResponseresponse,InputStreamis,StringfileName){
download(response,is,fileName,encoding);
}
/**
*文件下载
*@paramresponse
*@paramis文件输入流
*@paramfileName下载的文件名称
*@paramencoding编码格式
*/
publicstaticvoiddownload(HttpServletResponseresponse,InputStreamis,StringfileName,Stringencoding){
if(is==null||StringUtils.isBlank(fileName)){
return;
}
BufferedInputStreambis=null;
OutputStreamos=null;
BufferedOutputStreambos=null;
try{
bis=newBufferedInputStream(is);
os=response.getOutputStream();
bos=newBufferedOutputStream(os);
response.setContentType("application/octet-stream;charset="+encoding);
response.setCharacterEncoding(encoding);
response.setHeader("Content-disposition","attachment;filename="+URLEncoder.encode(fileName,encoding));
byte[]buffer=newbyte[1024];
intlen=bis.read(buffer);
while(len!=-1){
bos.write(buffer,0,len);
len=bis.read(buffer);
}
bos.flush();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(bis!=null){
try{
bis.close();
}catch(IOExceptione){}
}
if(is!=null){
try{
is.close();
}catch(IOExceptione){}
}
}
}
publicstaticStringgetEncoding(){
returnencoding;
}
publicstaticvoidsetEncoding(Stringencoding){
DownloadUtils.encoding=encoding;
}
}
如果文件保存在服务器的非网站目录下
StringfilePath="c:\\file.zip"; DownloadUtils.download(response,filePath);
如果文件是输入流
//is为文件输入流 //fileName为浏览器下载的文件名称 //encoding为文件名称编码,预防文件中有中文的时候产生乱码 StringfileName="file.zip"; Stringencoding="utf-8"; DownloadUtils.download(response,is,fileName,encoding);
Servlet中文件下载
packagecom.rhui.web.servlet;
importjava.io.IOException;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importcom.rhui.util.DownloadUtils;
@WebServlet("/download/servlet")
publicclassDownloadServletextendsHttpServlet{
privatestaticfinallongserialVersionUID=1L;
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
StringfilePath="c:\\file.zip";
DownloadUtils.download(response,filePath);
}
}
PS:图片下载(含防盗链功能)
packagecn.itcast.day06.web.servlet;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.net.URLEncoder;
importjavax.servlet.ServletContext;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassDownloadServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//实现防盗链功能
//获得referer头用于说明来访者来自哪里
Stringreferer=request.getHeader("referer");
if(referer==null||!referer.startsWith("http://localhost")){
//是盗链者
response.sendRedirect("/day06/index.jsp");
return;
}
//解决response中文乱码问题
response.setContentType("text/html;charset=utf-8");//设置消息体的编码
//通过http协议发送的http响应消息头不能出现中文中文必须要经过url编码
Stringfilename=URLEncoder.encode("美女.jpg","utf-8");
//通知浏览器以下载的方式读取资源
response.setHeader("content-disposition","attachment;filename="+filename);
//读取图片数据发给ie浏览器
StringwebPath="/download/美女.jpg";//相当于当前web应用的path
ServletContextservletContext=super.getServletContext();
InputStreamin=servletContext.getResourceAsStream(webPath);
OutputStreamout=response.getOutputStream();
intlen;
byte[]buffer=newbyte[1024];
while((len=in.read(buffer))!=-1)
out.write(buffer,0,len);
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
}