我正在尝试从http servlet向用户发送文件。 servlet运行一些识别测试(在请求上),然后向客户端发送一个文件。
这通常有效,但现在我打开我的TOMCAT服务器重定向到https,当我尝试访问servlet并从IE6或IE8下载文件时它失败了,我得到了这个例外:
java.lang.IllegalStateException: Cannot forward after response has been committed
(在localhost.log上)
和
ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error
(在servlet日志中)
执行发送(简化)的代码:
private void sendFile(HttpServletResponse response, byte[] file, String clientFileName)
{
ServletOutputStream op = null;
setContentType(response);
response.setHeader("Content-Disposition", "attachment; filename=\"" + clientFileName + "\"");
// send byte array to output buffer.
op = response.getOutputStream();
// Content Length must be set after all processing done.
response.setContentLength((int) file.length);
op.write(file);
}
这是从servlet发送文件的正确方法吗?什么是最好的方式?
谢谢!
更新
在此链接中使用@BalusC artice中的代码: http://balusc.blogspot.com/2007/07/fileservlet.html
这使它成功。
从Gmail使用IE6-IE8时仍然无效,因为gmail会在这些浏览器的下载过程中添加过滤阶段。
更新2
问题似乎与Gmail + Internet Explorer 6-8有关。 我假设gmail正在进行重定向(如果你在点击邮件中的链接后查看页面上的url,那实际上非常明显)。 Client-Pull技术是我唯一的解决方案吗?
答案 0 :(得分:0)
问题的解决方案是“Client-Pull”技术。
通过向标头添加Refresh
值,我们会让浏览器询问该文件。
这是我能够达到的唯一解决方案,克服了当从电子邮件中按下链接时gmail将使用重定向的事实。
在代码中我这样做了:
response.setHeader("Refresh", "3; URL=\"" + url.toString() + "\"");
forwardToJSP(request, response, "waitForBrowserRefreshPage.jsp");
含义 - 3秒后询问用户指定的URL,然后将该文件传递给客户端。
forwardToJSP
方法显示“您将很快转发,此处链接如果失败”消息。