从GWT客户端代码触发下载servlet,而不会丢失状态或侵入

时间:2013-05-08 09:23:49

标签: gwt servlets download

在那里,我对那些花哨的网络技术相当新,缺乏经验,对于可能愚蠢的问题感到抱歉。我有一个GWT应用程序

  • 在服务器端生成Excel工作表,
  • 将其存储在指定的位置
  • 应在导出后触发下载已创建的文件 并将其保存在服务器上。

到目前为止,一切都按预期工作,我现在唯一的问题是我不能为我的生活找到一种正确触发文件下载的方法。

下载本身由servlet处理,这个主题非常好,涵盖了各种问题。到目前为止我发现的所有问题中遗漏的是:“我如何在不失去GWT状态或没有打开一个阻碍的新窗口的情况下调用/触发/无论什么样的servlet?”。

以下片段在理论上有效,但在我看来并不是一个有效的选项。

String url = GWT.getHostPageBaseURL() + MyExport.SERVLET_URL_PATTERN + "?" + MyExport.FILENAME + "=" + result.getFileName();

// After this call my GWT state is lost
Window.Location.assign(url);

// obstrusive pop-up that is blocked by most browsers anyway
Window.open(url, "NameOfNewWindow", "resizable,scrollbars,status");

我尝试从我的演示者类中设置这些调用可能是有意义的。 提前抱歉,如果我没有找到正确的问题并且这是重复的,我将继续搜索并发布我找到的所有内容。

2 个答案:

答案 0 :(得分:2)

IFrame方法对我很有效。 在客户端的某个实用程序类中,您可以提供一个简单的静态“triggerDownload(String url)”

IFrame:

<iframe src="javascript:''" id="__gwt_downloadFrame" tabIndex='-1' style="position: absolute; width: 0; height: 0; border: 0; display: none;"></iframe>

触发下载的代码:

import com.google.gwt.dom.client.Document;
import com.google.gwt.user.client.ui.Frame;

public class Utils

  private static Frame downloadFrame;

  public static void triggerDownload(final String url) {
    if (url == null) {
      throw new IllegalArgumentException("URL must not be null");
    } // if

    if (downloadFrame == null) {
      downloadFrame = Frame.wrap(Document.get().getElementById("__gwt_downloadFrame"));
    } // if
    downloadFrame.setUrl(url);
  } // triggerDownload()
} // class Utils

答案 1 :(得分:0)

我在一个下载服务器端生成的pdf的应用程序中使用类似于Window.open代码的代码,与您尝试的非常相似。它不会导致弹出窗口,因为servlet流的文件的内容类型设置正确:

// Client side code in a click handler that triggers the download
Window.open("PromoPriceList?fileKey=" + itemKey, "_blank", "");


// In the servlet that is called, resp is the HttpServletResponse
resp.setContentType("application/pdf");
resp.setDateHeader("Expires",0);
resp.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
resp.setHeader("Pragma", "public");
resp.setHeader("Content-Disposition", "inline; filename=" + /* name for client */);
resp.setContentLength(/* size of file */);
// Stream the content with resp.getOutputStream().write(...)