Странное исключение EOF при попытке загрузить файл из приложения GWT - PullRequest
1 голос
/ 23 декабря 2010


Я пытаюсь загрузить файл с клиента GWT. На стороне сервера есть сервлет, который генерирует содержимое файла в соответствии с запросом и отправляет его обратно клиенту.

Сценарии испытаний:

Сценарий 1 Если я напрямую нажимаю URL-адрес сервлета, это всегда дает мне желаемый результат без каких-либо проблем.

Сценарий 2 Используя клиент GWT на IE8, я могу скачать файл без каких-либо изменений кода. Однако на другом компьютере, как только я пытаюсь записать содержимое файла в поток вывода ответа, я получаю исключение 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)
at java.io.BufferedOutputStream.flush (неизвестный источник)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet (ServiceDataExporterServlet.java:110)
на javax.servlet.http.HttpServlet.service (HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:717) Создание входного потока ....

Код сервлета следующий:

попробовать
{
output = new BufferedOutputStream (response.getOutputStream (), DEFAULT_BUFFER_SIZE);
byte [] buffer = новый байт [DEFAULT_BUFFER_SIZE];
длина int;
int bytesWritten = 0;
while ((length = data.read (buffer))> 0) {
bytesWritten + = длина;
output.write (буфер, 0, длина);
}
output.flush () // На данный момент я сталкиваюсь с исключением EOF.

где данные являются inputStream

Посредством переменной bytesWritten я подтвердил, что во всех трех сценариях содержимое было записано одинаковым образом в выходной поток. Но не уверен, почему он не работает на некоторых компьютерах.


Любые баллы будут высоко оценены.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2016

Это происходит также, если OutputStream сбрасывает после InputStream, как это: myInputStream.close ();myOutputStream.flush ();myOutputStream.close (); это должно быть как: myOutputStream.flush ();myInputStream.close ();myOutputStream.close (); Надеюсь, это поможет: -)

0 голосов
/ 03 февраля 2011

Я делаю что-то подобное для загрузки файлов с 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");
    }
}

У меня есть сервлет, который ожидает идентификатор, а затем я получаю путь к соответствующему файлу и отправляю его в браузер с кодом выше.

На стороне клиента:

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);
            }
        });

Надеюсь, это поможет вам.

Удачного кодирования!

...