Службы RPC GWT могут отправлять только объекты Java обратно клиенту. Чтобы отправить файл обратно пользователю, вам нужно использовать не-GWT Java-сервлет. Вот некоторый код, который я использовал ранее для обслуживания изображений JPEG из репозитория.
public class ImageServlet extends HttpServlet {
private final String repository = "/var/images/";
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String filename = request.getParameter("file");
// Security: '..' in the filename will let sneaky users access files
// not in your repository.
filename = filename.replace("..", "");
File file = new File(repository + filename);
if (!file.exists())
throw new FileNotFoundException(file.getAbsolutePath());
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-disposition", "attachment;filename=\"" + filename + "\"");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
byte[] buf = new byte[1024];
while (true) {
int length = bis.read(buf);
if (length == -1)
break;
bos.write(buf, 0, length);
}
bos.flush();
bos.close();
bis.close();
}
}
«Content-disposition: attachment» должно приводить к тому, что большинство браузеров загружают файл вместо его отображения, а имя файла по умолчанию соответствует тому, что вы предоставляете. Вы можете использовать этот сервлет так, чтобы пользователь вызвал RPCService, который у вас уже есть, который сохраняет файл в папку репозитория. Затем вы связываете или перенаправляете их на этот сервлет с URL-адресом, таким как http://your.domain.com/fileServlet?file=myFile.jpg. Очевидно, что при такой настройке у вас возникает угроза безопасности, когда пользователи могут загружать файлы других людей, если они могут угадать имена файлов.
Что вы можете сделать, это объединить код базы данных из вашей службы RPC с этим сервлетом. Нет необходимости сохранять файл где-либо на сервере, вы можете взять результаты своей базы данных и записать их в response.getOutputStream () или response.getWriter () точно так же, как вы записали бы их в файл, за исключением того, что результат идет прямо к пользователю. Пока вы правильно установите заголовки контента, пользователь не заметит разницы.
Вы не можете вызвать этот метод из другого сервлета, единственный способ заставить браузер загружать его в виде файла, это получить к нему доступ через обычный HTTP-запрос. Сначала вы объявляете сервлет в своем файле web.xml, как если бы вы использовали службу RPC GWT:
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>
com.package.ImageServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/imageServlet</url-pattern>
</servlet-mapping>
Теперь любые запросы HTTP GET, идущие на http://your.tomcat.server/webapp/imageServlet, будут обрабатываться ImageServlet.doGet (). Затем на стороне клиента вы можете сделать обычную HTML-ссылку на файл:
new HTML("<a href='" + GWT.getHostPageBaseURL() + "imageServlet?file=" + filename + "'>download</a>");
... или, вы должны иметь возможность поместить это в ClickHandler (я не проверял это):
Window.Location.assign(GWT.getHostPageBaseURL() + "imageServlet?file=" + filename);