【问题标题】:Weird EOF Exception while trying to download file from GWT application尝试从 GWT 应用程序下载文件时出现奇怪的 EOF 异常
【发布时间】:2011-05-29 21:04:36
【问题描述】:


我正在尝试从 GWT 客户端下载文件。在服务器端有一个 servlet,它根据请求生成文件内容并将其发送回客户端。

测试场景:

场景 1 如果我直接点击 servlet 的 url,它总是给我想要的结果,没有任何问题。

场景 2 在 IE8 上使用 GWT 客户端,我无需任何代码更改即可下载文件。但是,在其他计算机上,一旦我尝试在响应输出流上写入文件内容,就会出现 EOF 异常。

org.mortbay.jetty.EofException
在 org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:760)
在 org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.java:566)
在 org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:911)
在 java.io.BufferedOutputStream.flush(未知来源)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet(ServiceDataExporterServlet.java:110)
在 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
在 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)创建输入流....

servlet 代码如下:

试试
{
输出 = 新的 BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
字节[] 缓冲区 = 新字节[DEFAULT_BUFFER_SIZE];
整数长度;
int bytesWritten=0;
而 ((长度 = data.read(buffer)) > 0) {
bytesWritten+=长度;
output.write(缓冲区,0,长度);
}
output.flush() // 此时我面临 EOF 异常。

其中数据是输入流

通过 bytesWritten 变量,我已经确认在所有三个场景中,内容都以相同的方式写入输出流。但不知道为什么它在某些计算机上不起作用。


任何点都将受到高度评价。

【问题讨论】:

    标签: gwt ioexception eofexception


    【解决方案1】:

    我这样做是为了用 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);
                }
            });
    

    希望对你有帮助。

    编码愉快!

    【讨论】:

      【解决方案2】:


      如果 OutputStream InputStream 关​​闭后刷新也会发生这种情况,如下所示:
      myInputStream.close();
      myOutputStream.flush();
      myOutputStream.close();


      它应该是这样的:
      myOutputStream.flush();
      myInputStream.close();
      myOutputStream.close();

      希望它有所帮助:-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-08
        • 2015-08-13
        相关资源
        最近更新 更多