Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF How to redirect from backing bean to a URL dynamically constructed in the backing bean?

Tags:

jsf

primefaces

An example should hopefully demonstrate the issue. I have 10 documents that are displayed on the page, 3 of them have additional information contained inside zip packages. During the initial page load, I only know which documents have this additional information, I do not know the URL to these zip files. So then, I display a link ('Get Zip Package') to the 3 documents which contain additional zip files. When user clicks on 'Get Zip Package', it calls a method in the backing bean which goes to the database to figure out the URL of the zip package. Once this is done, I would like to serve the zip package to the browser which would then pop up as Save As... dialog and user can save the zip package.

I have tried two approaches but neither of them work.

Approach 1

<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;
}

Approach 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()}"/>
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;
}

As the page loads and the 10 documents are displayed, the 'Get Zip Package' link (for the 3 documents) points to nothing, essentially has the same URL as the page. When I click on it, it sends a GET request to the server and calls the backing bean function as well. With approach 1, the browser does appear to wait for the backing bean method to finish before it begins rendering a response. With approach 2, there is no wait and the browser immediately reloads the page. I suspect that since the 'Get Zip Package' link points to the page itself, browser's GET request gets processed first and the backing bean method's response simply gets lost.

A third approach (I have not tried yet) which I suspect will work just fine is to invoke a Servlet which would then serve up the zip package. But seeing how I have a direct URL to the zip package, I was hoping there would be a way to serve that to the browser without getting a Servlet involved.

Any suggestion(s) or approach(es) which would allow me to use the URL without invoking a Servlet are most welcome. Of course, if Servlet is the only 'proper' way of doing this, I will certainly do that.

Thank you.

like image 687
Harinder Avatar asked Nov 27 '12 21:11

Harinder


1 Answers

You can try with this kind of logic :

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect(context.getRequestContextPath() + "download-page.jsf?product=" + product + "&version=" + version);
like image 179
Alexandre Lavoie Avatar answered Oct 02 '22 19:10

Alexandre Lavoie