使用GWT中的RequestBuilder处理附件


问题内容

我正在从GWT客户端向HTTPServlet发出HTTP POST请求。该Servlet从请求内容创建PDF文件,并将其写入响应流。

响应流的标题为:

Content-Disposition: attachment; filename=report.pdf

我想在用户浏览器的新窗口中打开此PDF或提示他下载它。

import com.google.gwt.http.client.*;
...

String url = "http://www.myserver.com/getData?type=3";
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));

try {
  Request request = builder.sendRequest(data, new RequestCallback() {
    public void onError(Request request, Throwable exception) {
       // Couldn't connect to server (could be timeout, SOP violation, etc.)     
    }

    public void onResponseReceived(Request request, Response response) {
      if (200 == response.getStatusCode()) {
          // Process the response in response.getText()
          // Window.open(url, "_blank", "");
      } else {
        // Handle the error.  Can get the status text from response.getStatusText()
      }
    }       
  });
} catch (RequestException e) {
  // Couldn't connect to server        
}

我应该如何处理onResponseRecieved中的响应?


问题答案:

我认为在这种情况下,您不应使用单个RequestBuilderAJAX调用。您可以通过调用常规调用并让浏览器处理PDF响应(使用PDF查看器插件显示它或打开“保存”对话框)来依靠默认的浏览器行为。

有几种替代方法可以实现此目的:

  1. 如果可以在GET请求中传递数据(仅适用于较小的数据量),则可以使用数据作为GET参数创建URL,然后使用Window.open()打开新的浏览器窗口,并传递包含数据的URL。

  2. 对于大量数据,您可以先将数据发布RequestBuilder到服务器上以暂时存储数据,然后在RequestCallback.onResponseReceived()中打开一个新的浏览器窗口,该窗口带有短网址,如上面的替代方法1所示。在服务器端,您必须拆分PDF生成Servlet分为两部分:具有POST方法的数据存储servlet(即,将数据存储到Web会话中)和具有GET方法的PDF渲染servlet,其将数据从会话中删除(并删除)并且不会需要大参数。

  3. 使用方法POST,数据的隐藏字段和PDF生成Servlet URL创建一个表单。用数据填充隐藏的字段并以编程方式提交表单(即FormPanel.submit())。如果FormPanel使用目标名称创建浏览器,则浏览器会打开一个新窗口或使用指定的框架来处理响应。