JSF如何从支持bean重定向到在辅助bean中动态构造的URL?

Har*_*der 11 jsf primefaces

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

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

方法1

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

方法2

<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()}"/>
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢.

Ale*_*oie 33

你可以试试这种逻辑:

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect(context.getRequestContextPath() + "download-page.jsf?product=" + product + "&version=" + version);
Run Code Online (Sandbox Code Playgroud)