我正在尝试从GWT客户端下载文件。在服务器端,有一个servlet,它根据请求生成文件内容并将其发送回客户端。
测试场景:
场景1 如果我直接点击了servlet的url,它总是给我想要的结果而没有任何问题。
场景2 在IE8上使用GWT客户端,我可以在没有任何代码更改的情况下下载文件。但是,在我尝试在响应输出流上写入文件内容时,在其他计算机上,我得到了EOF异常。
org.mortbay.jetty.EofException
在org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:760)
at org.mortbay.jetty.AbstractGenerator $ Output.flush(AbstractGenerator.java:566)
at org.mortbay.jetty.HttpConnection $ Output.flush(HttpConnection.java:911)
在java.io.BufferedOutputStream.flush(未知来源)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet(ServiceDataExporterServlet.java:110)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:717)创建输入流....
servlet代码如下:
尝试
{
output = new BufferedOutputStream(response.getOutputStream(),DEFAULT_BUFFER_SIZE);
byte [] buffer = new byte [DEFAULT_BUFFER_SIZE];
int length;
int bytesWritten = 0;
while((length = data.read(buffer))> 0){
bytesWritten + =长度;
output.write(buffer,0,length);
}
output.flush()//此时我面临EOF异常。
其中data是inputStream
通过bytesWritten变量的方式,我已经确认在所有三种场景中,内容在输出流中以相同的方式编写。但不确定为什么它不适用于某些计算机。
任何积分都会受到高度赞赏。
答案 0 :(得分:0)
我做这样的事情用GWT下载文件
在服务器端:
public static void sendFileToClient(String path, String filename,
int contentLen, HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException
{
String ua = request.getHeader("User-Agent").toLowerCase();
boolean isIE = ((ua.indexOf("msie 6.0") != -1) || (ua
.indexOf("msie 7.0") != -1)) ? true : false;
String encName = URLEncoder.encode(filename, "UTF-8");
// Derived from Squirrel Mail and from
// http://www.jspwiki.org/wiki/BugSSLAndIENoCacheBug
if (request.isSecure())
{
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "-1");
response.addHeader("Cache-Control", "no-cache");
}
else
{
response.addHeader("Cache-Control", "private");
response.addHeader("Pragma", "public");
}
if (isIE)
{
response.addHeader("Content-Disposition", "attachment; filename=\"" + encName + "\"");
response.addHeader("Connection", "close");
response.setContentType("application/force-download; name=\"" + encName + "\"");
}
else
{
response.addHeader("Content-Disposition", "attachment; filename=\""
+ encName + "\"");
response.setContentType("application/octet-stream; name=\""
+ encName + "\"");
if (contentLen > 0)
response.setContentLength(contentLen);
}
try
{
FileInputStream zipIn = new FileInputStream(new File(path));
ServletOutputStream out = response.getOutputStream();
response.setBufferSize(8 * 1024);
int bufSize = response.getBufferSize();
byte[] buffer = new byte[bufSize];
BufferedInputStream bis = new BufferedInputStream(zipIn, bufSize);
int count;
while ((count = bis.read(buffer, 0, bufSize)) != -1)
{
out.write(buffer, 0, count);
}
bis.close();
zipIn.close();
out.flush();
out.close();
}
catch (FileNotFoundException e)
{
System.out.println("File not found");
}
catch (IOException e)
{
System.out.println("IO error");
}
}
我有一个需要id的servlet,然后我得到相关的文件路径,然后用上面的代码将它提供给浏览器。
在客户端:
public class DownloadIFrame extends Frame implements LoadHandler,
HasLoadHandlers
{
public static final String DOWNLOAD_FRAME = "__gwt_downloadFrame";
public DownloadIFrame(String url)
{
super();
setSize("0px", "0px");
setVisible(false);
RootPanel rp = RootPanel.get(DOWNLOAD_FRAME);
if (rp != null)
{
addLoadHandler(this);
rp.add(this);
setUrl(url);
}
else
openURLInNewWindow(url);
}
native void openURLInNewWindow(String url) /*-{
$wnd.open(url);
}-*/;
public HandlerRegistration addLoadHandler(LoadHandler handler)
{
return addHandler(handler, LoadEvent.getType());
}
public void onLoad(LoadEvent event)
{
}
}
在您托管的网页中添加此iframe
<iframe src="javascript:''" id="__gwt_downloadFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
然后下载一个像这样的文件:
btnDownload.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent arg0)
{
String url = GWT.getModuleBaseURL()
+ "/downloadServlet?id=[FILE_ID]";
new DownloadIFrame(url);
}
});
我希望这会对你有所帮助。
快乐的编码!
答案 1 :(得分:0)
如果在 InputStream关闭后OutputStream刷新 ,也会发生这种情况,如下所示:
的 myInputStream.close();
myOutputStream.flush();
myOutputStream.close(); 强>
应该是这样的:
的 myOutputStream.flush();
myInputStream.close();
myOutputStream.close();
强>
希望它有所帮助: - )