Скачать динамический файл с GWT - PullRequest
9 голосов
/ 13 мая 2010

У меня есть страница GWT, где пользователь вводит данные (дата начала, дата окончания и т. Д.), Затем эти данные отправляются на сервер через вызов RPC. На сервере я хочу создать отчет Excel с POI и позволить пользователю сохранить этот файл на своем локальном компьютере.

Это мой тестовый код для потоковой передачи файла обратно клиенту, но по какой-то причине я думаю, что он не знает, как передавать файл клиенту при использовании RPC:

public class ReportsServiceImpl extends RemoteServiceServlet implements ReportsService {
    public String myMethod(String s) {

        File f = new File("/excelTestFile.xls");

        String filename = f.getName();

        int length = 0;

        try {
            HttpServletResponse resp = getThreadLocalResponse();
            ServletOutputStream op = resp.getOutputStream();
            ServletContext context = getServletConfig().getServletContext();
            resp.setContentType("application/octet-stream");
            resp.setContentLength((int) f.length());
            resp.setHeader("Content-Disposition", "attachment; filename*=\"utf-8''" + filename + "");

            byte[] bbuf = new byte[1024];
            DataInputStream in = new DataInputStream(new FileInputStream(f));

            while ((in != null) && ((length = in.read(bbuf)) != -1)) {
                op.write(bbuf, 0, length);
            }

            in.close();
            op.flush();
            op.close();

        }
        catch (Exception ex) {
            ex.printStackTrace();
        }

        return "Server says: " + filename;
    }
}

Я где-то читал в Интернете, что вы не можете выполнять потоковую передачу файлов с помощью RPC, и для этого мне нужно использовать сервлет. Есть ли пример того, как использовать сервлет и как вызвать этот сервлет из ReportsServiceImpl . Мне действительно нужно сделать сервлет или есть возможность вернуть его обратно с моим RPC?

Ответы [ 3 ]

14 голосов
/ 13 мая 2010

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

На стороне клиента вы должны создать нормальную ссылку привязки с параметрами, передаваемыми через строку запроса. Что-то вроде <a href="http://myserver.com/myservlet?parm1=value1&.."</a>.

На стороне сервера переместите свой код в стандартный сервлет, который НЕ наследуется от RemoteServiceServlet. Прочитайте параметры объекта запроса, создайте Excel и отправьте его обратно клиенту. Браузер автоматически откроет диалоговое окно загрузки файла.

2 голосов
/ 04 января 2013

Вы можете сделать это, просто используя GWT RPC и URI данных :

  1. В вашем примере myMethod возвращает содержимое файла.
  2. На стороне клиента отформатируйте URI данных с полученным содержимым файла.
  3. Используйте Window.open, чтобы открыть диалоговое окно сохранения файла с передачей отформатированного DataURI .

Взгляните на эту ссылку, чтобы понять использование URI данных :

Экспорт в CSV в JQuery

0 голосов
/ 23 марта 2011

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

И, исходя из вашего кода, кажется, что вы пытаетесь запустить стандартный механизм браузера для обработки данного типа MIME, изменяя ответ на сервере, чтобы браузер распознал его как загрузку ... открыть сохранить диалог, например. Для этого вам нужно, чтобы браузер сделал запрос для вас, и вам нужен сервлет для обработки запроса. Это можно сделать с помощью остальных URL, но в конечном итоге вам понадобится сервис, чтобы сделать это.

По сути, вам нужно установить URL-адрес окна браузера на URL, который отправляет обратно измененный объект ответа.

Так что этот вопрос (о потоковой передаче) не совсем совместим с примером кода. Необходимо скорректировать один или другой подход (протоколы связи или измененный сервером объект ответа).

Самый простой способ настройки - это способ связи.

...