GWT 的 RPC 服务只能将 java 对象发送回客户端。要将文件发送回用户,您需要使用非 GWT java servlet。这是我之前使用过的一些代码,用于从存储库提供 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();
}
}
“内容处置:附件”应该会导致大多数浏览器下载文件而不是显示它,文件名默认为您提供的任何文件名。使用此 servlet 的方法是让用户调用您已有的 RPCService,这会将文件保存到存储库文件夹中。然后,您可以使用以下 url 将它们链接或重定向到此 servlet:http://your.domain.com/fileServlet?file=myFile.jpg http://your.domain.com/fileServlet?file=myFile.jpg。显然,使用此设置会存在安全风险,如果用户可以猜测文件名,他们就可以下载其他人的文件。
您可能想要做的是将 RPC 服务中的数据库代码合并到此 servlet 中。无需将文件保存在服务器上的任何位置,您可以获取数据库结果并将其写入response.getOutputStream() 或response.getWriter(),其方式与将它们写入文件的方式完全相同,只是结果会变为直接给用户。只要您正确设置内容标题,用户就不会注意到差异。
您无法从另一个 servlet 调用此方法,使浏览器将其作为文件下载的唯一方法是通过普通 HTTP 请求访问它。首先,您在 web.xml 文件中声明 servlet,就像声明 GWT RPC 服务一样:
<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 http://your.tomcat.server/webapp/imageServlet将被 ImageServlet.doGet() 获取。然后在客户端,您可以创建一个指向该文件的普通 html 链接:
new HTML("<a href='" + GWT.getHostPageBaseURL() + "imageServlet?file=" + filename + "'>download</a>");
...或者你should能够将其放入 ClickHandler 中(我还没有测试过):
Window.Location.assign(GWT.getHostPageBaseURL() + "imageServlet?file=" + filename);