java中下载文件最好用servlet,我在用普通的类实现下载功能时提示getOutputStream has already been commit 的error,查了好多资料都没有解决,(有的说response要reset,有的说jsp页面中不能换行等等,我试过后都不行)用servlet来做则不会有这个问题,源代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = (String) request.getParameter("fileName");
String path = "/dept/hr/files/training/" + fileName;
String realPath = this.getServletContext().getRealPath(path);
File f = new File(realPath);
if (!f.exists()) {
response.sendError(404, "File not found!");
return;
}
fileName = new String(fileName.getBytes("GB2312"), "ISO8859_1"); //处理文件中含中文的问题,不是万能的
boolean isOnLine = false;
response.reset(); //非常重要
if (isOnLine) { //在线打开方式
URL u = new URL("file:///" + realPath);
response.setContentType(u.openConnection().getContentType());
response.setHeader("Content-Disposition",
"inline; filename=" + f.getName());
} else { //纯下载方式
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition",
"attachment; filename=" + fileName);
}
byte[] buf = new byte[1024];
int len = 0;
BufferedInputStream br = null;
OutputStream out = null;
try {
br = new BufferedInputStream(new FileInputStream(f));
out = response.getOutputStream();
while ((len = br.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.flush();
} catch (Exception e) {
//e.printStackTrace();
} finally {
if (br != null) {
br.close();
br = null;
}
if (out != null) {
out.close();
out = null;
}
}
}
本源代码是基于axman的版本,根据实际需要稍微改了改,我用的是weblogic,当下载.xls等文件时如果用户选择取消则有时报Connection reset by peer:socket write error,其他类型如.doc文件则不会出错,tomcat下不知道有没有这个问题,网上查了半天不知所以然,但有一点可以肯定,就是它并不影响程序的正常运行,所以我把错误输出语句注释掉了。