Foren

File Download in JSF Portlet

N. H., geändert vor 7 Jahren.

File Download in JSF Portlet

Junior Member Beiträge: 71 Beitrittsdatum: 14.11.13 Neueste Beiträge
Hello Together,
I have the following problem. I want to write a download portlet in JSF.

I write a resourcehandler for the files and it works fine, but I must implement 2 spezial functionallities.

1. Update a database row after the download
2. When the file was downloaded bevor then first a confirm dialog had to appear an ask the user "Shure you want to download again"

in JSF I used a simple h:outputlink and try to do the database update with an f:ajax listener like the following



<h:outputlink id="downloadButton" target="new" value="#{file.requestPath}">
			<f:ajax event="click" listener="#{download.download(file)}" render="@form" />
</h:outputlink>	


This worked fine but what happened when the link crashed how can I interrupt the ajax so the db will not be updated ?

The second funtion I tried to resolved like this

	<h:outputlink onclick="return confirm('Are you shure ?');" id="downloadButton" target="new" value="#{file.requestPath}">
			<f:ajax event="click" listener="#{download.download(file)}" render="@form" />
	</h:outputlink>	


But that does not work emoticon.

I hope you understand and can help me

Kind Regards N.H.
thumbnail
Neil Griffin, geändert vor 7 Jahren.

RE: File Download in JSF Portlet

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
N. H.:
This worked fine but what happened when the link crashed how can I interrupt the ajax so the db will not be updated ?


Please describe in more detail what you mean by "when the link crashed"

Thank you,

Neil
N. H., geändert vor 7 Jahren.

RE: File Download in JSF Portlet

Junior Member Beiträge: 71 Beitrittsdatum: 14.11.13 Neueste Beiträge
Hello Neil,

in the getInputStream method of the resource we had an database Connection to get the file dynamically from the database.

Maybe the connection lost or something else so the link "brokes" because the resource could not be load.

Kind regards
Natalie
thumbnail
Neil Griffin, geändert vor 7 Jahren.

RE: File Download in JSF Portlet

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
Hi Natalie,

I assume that your ResourceHandler extends ResourceHandlerWrapper (similar to CustomerResourceHandler.java in our jsf-export-pdf-portlet demo). If that's the case, then it might be better to update the database by overriding the handleResourceRequest(FacesContext) method (see JavaDoc for more info):
@Override
public void handleResourceRequest(FacesContext facesContext) throws IOException {
    super.handleResourceRequest(facesContext);
    // update the database now that the ResourceHandler has successfully written all the bytes to the response
}

With regard to updating the UI, you probably have a timing problem. When the user clicks on the "downloadButton" h:outputLink (an anchor tag) two requests happen:
1. The onclick attribute causes jsf.js to trigger an XmlHttpRequest POST
2. The href attribute causes a second HTTP GET to the ResourceHandler which causes the file to be output to a new browser tab

The problem is that the two requests are not aware of each other. In fact, one might complete before the other. So there is no way for the XmlHttpRequest to know whether or not the HTTP GET to the ResourceHandler was successful.

Just an idea, but one way you might be able to solve the timing problem would be to do something like this instead:

<h:form id="myForm" binding="#{myFormClientId}">
    <a onclick="downloadFile(this, event, '#{file.requestPath}'); return false;">Download</a>
</h:form>

function downloadFile(element, event, requestPath) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 &amp;&amp; xhr.status == 200) {
            // Use the JSF JavaScript API to submit the form and update the UI Asynchronously
            jsf.ajax.request(element,event, {execute:'#{myFormClientId}', render:'#{myFormClientId}'});
    };
    xhr.open("GET", requestPath, true);
    xhr.send();
}


Kind Regards,

Neil