留言板

File Download in JSF Portlet

N. H.,修改在7 年前。

File Download in JSF Portlet

Junior Member 帖子: 71 加入日期: 13-11-14 最近的帖子
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,修改在7 年前。

RE: File Download in JSF Portlet

Liferay Legend 帖子: 2655 加入日期: 05-7-27 最近的帖子
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.,修改在7 年前。

RE: File Download in JSF Portlet

Junior Member 帖子: 71 加入日期: 13-11-14 最近的帖子
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,修改在7 年前。

RE: File Download in JSF Portlet

Liferay Legend 帖子: 2655 加入日期: 05-7-27 最近的帖子
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