一、如何使用
如果此Servlet命名为download,请求的URL为:/download?path=xxx,请求后出现下载窗口:
二、源码
import
java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
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 FileDownload extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// 服务器相对路径
String path = req.getParameter( " path " );
// 服务器绝对路径
path = getServletContext().getRealPath( " / " ) + path;
// 检查文件是否存在
File obj = new File(path);
if ( ! obj.exists()) {
res.setContentType( " text/html;charset=GBK " );
res.getWriter().print( " 指定文件不存在! " );
return ;
}
// 读取文件名:用于设置客户端保存时指定默认文件名
int index = path.lastIndexOf( " // " ); // 前提:传入的path字符串以“/”表示目录分隔符
String fileName = path.substring(index + 1 );
// 写流文件到前端浏览器
ServletOutputStream out = res.getOutputStream();
res.setHeader( " Content-disposition " , " attachment;filename= " + fileName);
BufferedInputStream bis = null ;
BufferedOutputStream bos = null ;
try {
bis = new BufferedInputStream( new FileInputStream(path));
bos = new BufferedOutputStream(out);
byte [] buff = new byte [ 2048 ];
int bytesRead;
while ( - 1 != (bytesRead = bis.read(buff, 0 , buff.length))) {
bos.write(buff, 0 , bytesRead);
}
} catch (IOException e) {
throw e;
} finally {
if (bis != null )
bis.close();
if (bos != null )
bos.close();
}
}
}
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
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 FileDownload extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// 服务器相对路径
String path = req.getParameter( " path " );
// 服务器绝对路径
path = getServletContext().getRealPath( " / " ) + path;
// 检查文件是否存在
File obj = new File(path);
if ( ! obj.exists()) {
res.setContentType( " text/html;charset=GBK " );
res.getWriter().print( " 指定文件不存在! " );
return ;
}
// 读取文件名:用于设置客户端保存时指定默认文件名
int index = path.lastIndexOf( " // " ); // 前提:传入的path字符串以“/”表示目录分隔符
String fileName = path.substring(index + 1 );
// 写流文件到前端浏览器
ServletOutputStream out = res.getOutputStream();
res.setHeader( " Content-disposition " , " attachment;filename= " + fileName);
BufferedInputStream bis = null ;
BufferedOutputStream bos = null ;
try {
bis = new BufferedInputStream( new FileInputStream(path));
bos = new BufferedOutputStream(out);
byte [] buff = new byte [ 2048 ];
int bytesRead;
while ( - 1 != (bytesRead = bis.read(buff, 0 , buff.length))) {
bos.write(buff, 0 , bytesRead);
}
} catch (IOException e) {
throw e;
} finally {
if (bis != null )
bis.close();
if (bos != null )
bos.close();
}
}
}
三、web.xml配置
<
servlet
>
< servlet-name > FileDownload </ servlet-name >
< servlet-class > com.fastunit.test.FileDownload </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > FileDownload </ servlet-name >
< url-pattern > /download </ url-pattern >
</ servlet-mapping >
< servlet-name > FileDownload </ servlet-name >
< servlet-class > com.fastunit.test.FileDownload </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > FileDownload </ servlet-name >
< url-pattern > /download </ url-pattern >
</ servlet-mapping >
四、补充说明
本例只是一个简单实现,应用时需要在实际环境中处理以下问题:
1. 权限问题:结合实际系统增加用户权限控制
2. 中文文件名:中文问题与运行环境有关,不同环境下解决方式也有差异,一般可通过转码来解决。
3. 文件类型:文件类型统一时可直接指定,如res.setContentType("application/zip");文件类型不确定时可不设、设一个不存在的、或通过解析文件名后缀来设置,以实际测试通过为准。
4. 以上代码应该有个doget dopost的方法。附带一个上传文件代码,令下载文件正确代码
上传: 需要导入两个包:commons-fileupload-1.2.1.jar,commons-io-1.4.jar import java.io.File; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * 上传附件 * @author new * */ public class UploadAnnexServlet extends HttpServlet { private static String path = ""; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /* * post处理 * (non-Javadoc) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { path = this.getServletContext().getRealPath("/upload"); try { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload up = new ServletFileUpload(factory); List<FileItem> ls = up.parseRequest(request); for (FileItem fileItem : ls) { if (fileItem.isFormField()) { String FieldName = fileItem.getFieldName(); //getName()返回的是文件名字 普通域没有文件 返回NULL // String Name = fileItem.getName(); String Content = fileItem.getString("gbk"); request.setAttribute(FieldName, Content); } else { String nm = fileItem.getName().substring( fileItem.getName().lastIndexOf("//") + 1); File mkr = new File(path, nm); if (mkr.createNewFile()) { fileItem.write(mkr);//非常方便的方法 } request.setAttribute("result", "上传文件成功!"); } } } catch (Exception e) { e.printStackTrace(); request.setAttribute("result", "上传失败,请查找原因,重新再试!"); } request.getRequestDispatcher("/pages/admin/annex-manager.jsp").forward( request, response); } } 下载(i/o流)无需导包: import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 下载文件 * @author * */ public class DownloadFilesServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 8594448765428224944L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /* * 处理请求 * (non-Javadoc) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("fileName"); System.out.print("dddddddddd:" + name); // web绝对路径 String path = request.getSession().getServletContext().getRealPath("/"); String savePath = path + "upload"; // 设置为下载application/x-download response.setContentType("application/x-download"); // 即将下载的文件在服务器上的绝对路径 String filenamedownload = savePath + "/" + name; // 下载文件时显示的文件保存名称 String filenamedisplay = name; // 中文编码转换 filenamedisplay = URLEncoder.encode(filenamedisplay, "UTF-8"); response.addHeader("Content-Disposition", "attachment;filename=" + filenamedisplay); try { java.io.OutputStream os = response.getOutputStream(); java.io.FileInputStream fis = new java.io.FileInputStream( filenamedownload); byte[] b = new byte[1024]; int i = 0; while ((i = fis.read(b)) > 0) { os.write(b, 0, i); } fis.close(); os.flush(); os.close(); } catch (Exception e) { } } }