java 不同浏览器 下载文件 有的浏览器会调两次后台

u010653906 2015-08-19 09:18:40
下面是javascript生成表单,调后台进行下载的代码:
var form = $("<form>");
form.attr("style", "display:none");
form.attr("target", "");
form.attr("method", "post");
form.attr("action", "download");
var input = $("<input>");
input.attr("type", "hidden");
input.attr("name", "downLoadInfo");
input.attr('value', selectedInfo);
$("body").append(form);
form.append(input);
form.submit()

下面是servlet中执行下载的主要方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
String downLoadInfo = request.getParameter("downLoadInfo");
String realPath = getServletContext().getRealPath("/").replaceAll("\\\\", "/");
Set<String> fileSet = this.getFileSet(downLoadInfo, realPath + "video/");
response.setContentType("text/plain");
response.setHeader("Location","video.zip");
response.setHeader("Content-Disposition", "attachment; filename=video.zip");
ZipOutputStream out = null;
FileInputStream scratchFileIs = null;
FileInputStream in = null;
try {
out = new ZipOutputStream(response.getOutputStream());
Iterator<String> iterator = fileSet.iterator();
byte[] buffer = new byte[5120];
out.putNextEntry(new ZipEntry("log.txt"));
scratchFileIs = this.writeScratchFile(downLoadInfo, realPath + "video/scratchFile/");
int scratchFileLength = 0;
while((scratchFileLength = scratchFileIs.read(buffer)) > 0) {
out.write(buffer, 0, scratchFileLength);
}
out.closeEntry();
scratchFileIs.close();
while(iterator.hasNext()) {
File file = new File(iterator.next());
in = new FileInputStream(file);
out.putNextEntry(new ZipEntry(file.getName()));
int length = 0;
while((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.closeEntry();
in.close();
}
out.flush();
out.close();
} catch (IOException e) {
BasicConfigurator.configure();
logger.error("",e);
throw e;
} finally {
if(in != null) {
in.close();
in = null;
}
if(scratchFileIs != null) {
scratchFileIs.close();
scratchFileIs = null;
}
if(out != null) {
out.close();
out = null;
}
}
}

private FileInputStream writeScratchFile(String downLoadInfo, String fileURL) throws IOException {
File file = new File(fileURL + new Date().getTime() + (int)(Math.random()*1000) + ".txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String[] allRecordString = downLoadInfo.split("<os>");
for(int i=0 ; i<allRecordString.length ; i++) {
String record = "";
record = allRecordString[i].replace("<rs>", ",");
record = record.replace("undefined", "");
bw.write(record.split("<filename>")[0]);
bw.newLine();
}
bw.flush();
bw.close();
FileInputStream scratchFileIs = new FileInputStream(file);
if(file.exists()) {
file.delete();
}
return scratchFileIs;
}

private Set<String> getFileSet(String downLoadInfo, String dirURL) {
Set<String> fileSet = new HashSet<String>();
String[] allRecordString = downLoadInfo.split("<os>");
for(int i=0 ; i<allRecordString.length ; i++) {
if(new File(dirURL + allRecordString[i].split("<filename>")[1]).exists()) {
fileSet.add(dirURL + allRecordString[i].split("<filename>")[1]);
}
}
return fileSet;
}

用搜狗浏览器下载执行javascript的方法会调用两次后台,导致报:
ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error
这个异常,我写的代码中报此异常的是上面dopost方法中的红色标出位置。但是报这个异常不影响正常的下载。在网上查了很多资料,都没有对此异常很好的解决方法。现在查出的原因是,用搜狗浏览器进行下载,浏览器默认会选择搜狗下载器,用这个下载器就会调用两次后台,用IE浏览器或把搜狗浏览器的搜狗下载器关闭,将正常调用一次后台,并且不再抛出此异常。
问下各位大牛,对此有没有很好的解决办法。另外,是不是代码写的有问题,流没有很好的关闭。即使调用了两次servlet也不应该是抛出异常啊。
...全文
639 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
小小龙是爷 2016-12-13
  • 打赏
  • 举报
回复
引用 1 楼 u010653906 的回复:
问题大概我猜想是这样的,在安装了下载插件的浏览器进行下载,IE会首先调用一次后台,但没有开始下载,之后浏览器所带下载器会执行下载,并关闭IE下载,当IE下载关闭时,服务器抛出此异常。最后真正完成下载的是浏览器所带的下载器。不知道我的猜想是不是正确,如果正确,对此有什么解决的办法呢?仅仅在后台捕捉ClientAbortException而不处理这个异常么?
我对这个异常也是一头雾水,但是看了这个解释,发现人家说的合情合理,我估摸着就是这回事了,顶!!!
u010653906 2015-08-19
  • 打赏
  • 举报
回复
问题大概我猜想是这样的,在安装了下载插件的浏览器进行下载,IE会首先调用一次后台,但没有开始下载,之后浏览器所带下载器会执行下载,并关闭IE下载,当IE下载关闭时,服务器抛出此异常。最后真正完成下载的是浏览器所带的下载器。不知道我的猜想是不是正确,如果正确,对此有什么解决的办法呢?仅仅在后台捕捉ClientAbortException而不处理这个异常么?
香蕉猪 2015-08-19
  • 打赏
  • 举报
回复
为啥会下两次???浏览器的下载插件为啥不能用你的代码正常下载???你应该处理下载器对应的下载方式才对吧。。。

87,888

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧