使用GWT下载动态文件

时间:2010-05-12 20:50:27

标签: java gwt servlets rpc

我有一个GWT页面,用户输入数据(开始日期,结束日期等),然后这些数据通过RPC调用进入服务器。在服务器上,我想用POI生成Excel报告,并让用户将该文件保存在本地计算机上。

这是我将测试代码流回客户端的测试代码,但出于某种原因,我认为当我使用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做文件流,我必须使用Servlet。有没有关于如何使用Servlet以及如何从 ReportsServiceImpl 调用该servlet的示例。我是否真的需要制作一个servlet,或者可以使用我的RPC来回传它?

3 个答案:

答案 0 :(得分:14)

您必须制作常规Servlet,无法ReportsServiceImpl流式传输二进制数据。此外,无法从ReportsServiceImpl调用servlet - 您的客户端代码必须直接调用servlet。

在客户端,您必须使用通过查询字符串传递的参数创建常规锚链接。类似于<a href="http://myserver.com/myservlet?parm1=value1&.."</a>

在服务器端,将代码移动到标准Servlet,该Servlet不从RemoteServiceServlet继承。从请求对象中读取参数,创建excel并将其发送回客户端。浏览器将自动弹出文件下载对话框。

答案 1 :(得分:2)

您只需使用GWT RPC和Data URIs

即可
  1. 在您的示例中,让您的myMethod返回文件内容。
  2. 在客户端,使用收到的文件内容格式化Data URI
  3. 使用Window.open打开文件保存对话框,传递格式化的DataURI
  4. 请参阅此参考,以了解Data URI用法:

      

    Export to csv in jQuery

答案 2 :(得分:0)

可以通过多种方式从RPC通道获取您想要的二进制数据...例如,uuencode。但是,您仍然需要让浏览器将文件作为下载来处理。

根据您的代码,您似乎试图通过修改服务器中的响应来触发标准浏览器机制来处理给定的mime类型,以便浏览器将其识别为下载...打开例如,保存对话框。要做到这一点,您需要让浏览器为您发出请求,并且您需要servlet来处理请求。它可以通过其他网址来完成,但最终你需要一个服务才能做到这一点。

实际上,您需要将浏览器窗口URL设置为发送回修改后的响应对象的URL。

所以这个问题(关于流媒体)与代码示例并不真正兼容。必须调整一个或另一个(通信协议或服务器修改的响应对象)方法。

最容易调整的是沟通方式。