【问题标题】:Download dynamic file with GWT使用 GWT 下载动态文件
【发布时间】:2011-02-18 20:13:30
【问题描述】:

我有一个 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 将其流式传输回来?

【问题讨论】:

  • 请详细说明问题。 “它不知道”并不是真正的描述性。究竟会发生什么?究竟发生了什么?
  • @sri 的回答很有道理。现在轮到我发布一些 cmets:1) DataInputStream 是多余的。直接使用FileInputStream。毕竟您需要InputStream 类中定义的read() 方法。 2) in != null 检查也是多余的,因为它 never 为空(您使用new 创建了新的检查,它永远不能为空)。 3) Content-Disposition 标头在 filename 部分中看起来格式不正确。要了解如何进行 basic 文件服务,您可能会发现 this article 很有用。祝你好运。

标签: java gwt servlets rpc


【解决方案1】:

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

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

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

【讨论】:

  • 是的,这是有道理的。感谢您的建议!
【解决方案2】:

您只需使用 GWT RPC 和 Data URIs 就可以做到这一点:

  1. 在您的示例中,让您的myMethod 返回文件内容。
  2. 在客户端,使用收到的文件内容格式化Data URI
  3. 使用Window.open 打开一个文件保存对话框,传递格式化的DataURI

看看这个参考,了解Data URI的用法:

Export to csv in jQuery

【讨论】:

  • 需要考虑的是 IE 6 和 7 不支持 DATA URI。但 IE8 有部分支持。
【解决方案3】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    相关资源
    最近更新 更多