11

一个例子应该有望证明这个问题。我在页面上显示了 10 个文档,其中 3 个包含在 zip 包中的附加信息。在初始页面加载期间,我只知道哪些文档有这些附加信息,我知道这些 zip 文件的 URL。然后,我显示一个链接(“获取 Zip 包”)指向包含附加 zip 文件的 3 个文档。当用户单击“获取 Zip 包”时,它会调用支持 bean 中的一个方法,该方法会进入数据库以找出 zip 包的 URL。完成后,我想将 zip 包提供给浏览器,然后浏览器会弹出另存为...对话框,用户可以保存 zip 包。

我尝试了两种方法,但它们都不起作用。

方法一

<p:commandLink actionListener="#{myBackingBean.zipPackage(aDocument)}"
               value="Get Zip Package"
               ajax="false"
               rendered="#{aDocument.packageAvailable}"/>
public String zipPackage(DocItem item){
  //logic here to figure out the URL for this item's zip package
  return packageLink;
}

方法二

<h:outputLink onclick="getPackageLink([{name:'product', value: '#{aResult.product}'}, {name:'version',value:'#{aResult.version}'}])"
   <h:outputText value="Get Documentation Package"/>
</h:outputLink>
<p:remoteCommand name="getPackageLink" actionListener="#{kbBackingBean.zipPackage()}"/>
public String zipPackage() {
  Map map = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
  String product = (String) map.get("product");
  String version = (String) map.get("version");
  //logic here to figure out the URL for this item's zip package
  return packageLink;
}

当页面加载并显示 10 个文档时,“获取 Zip 包”链接(用于 3 个文档)指向任何内容,基本上与页面具有相同的 URL。当我单击它时,它会向服务器发送一个 GET 请求并调用支持 bean 函数。使用方法 1,浏览器在开始呈现响应之前似乎确实在等待支持 bean 方法完成。使用方法 2,无需等待,浏览器会立即重新加载页面。我怀疑由于“获取 Zip 包”链接指向页面本身,浏览器的 GET 请求首先得到处理,而支持 bean 方法的响应只是丢失了。

我怀疑可以正常工作的第三种方法(我还没有尝试过)是调用一个 Servlet,然后它会提供 zip 包。但是看到我有一个指向 zip 包的直接 URL,我希望有一种方法可以在不涉及 Servlet 的情况下将其提供给浏览器。

任何允许我在不调用 Servlet 的情况下使用 URL 的建议或方法都非常受欢迎。当然,如果 Servlet 是这样做的唯一“正确”方式,我肯定会这样做。

谢谢你。

4

1 回答 1

33

您可以尝试使用这种逻辑:

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect(context.getRequestContextPath() + "download-page.jsf?product=" + product + "&version=" + version);
于 2012-11-27T22:26:38.927 回答