This is a unique and curious case to me of having problems in implementing a download button using jsf 2.
So I have defined a button like this:
<h:form id="downloadForm">
<h:commandButton value="Download" action="#{viewStatus.download()}" />
</h:form>
In my backing bean, the function looks like this:
public void download()
{
String filePath = "opt/myapplication/reports/myfile.csv";
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
try
{
File file = new File(filePath);
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/x-download");
Long fileLength = file.length();
ec.setResponseContentLength(fileLength.intValue());
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
OutputStream output = ec.getResponseOutputStream();
PrintWriter printWriter = new PrintWriter(output, true);
Scanner input = new Scanner(file);
while(input.hasNextLine())
{
String line = input.nextLine();
printWriter.write(line);
}
input.close();
output.close();
printWriter.close();
fc.responseComplete();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
As you can see, I have NOT used ajax in the button and I am using the function responseComplete() to end the response.
In my page, when I click the download button, no errors are thrown, but the cursor keeps on revolving indicating that some process is going on in the background. Its like an infinite loop is going on.
After banging my head for a thousand times, when I ran the same command in a fresh project, everything works. So I know that the code is correct.
Now let me show you my JSF lifecycle log:
AFTER PHASE: RESTORE_VIEW 1
BEFORE PHASE: APPLY_REQUEST_VALUES 2
AFTER PHASE: APPLY_REQUEST_VALUES 2
BEFORE PHASE: PROCESS_VALIDATIONS 3
AFTER PHASE: PROCESS_VALIDATIONS 3
BEFORE PHASE: UPDATE_MODEL_VALUES 4
AFTER PHASE: UPDATE_MODEL_VALUES 4
BEFORE PHASE: INVOKE_APPLICATION 5
AFTER PHASE: INVOKE_APPLICATION 5
As you can see, the sixth phase - "BEFORE PHASE: RENDER_RESPONSE 6" and "AFTER PHASE: RENDER_RESPONSE 6" does not come up ever. And hence I see the cursor revolving thing, because my browser is trying to render the view, but something is blocking it, and hence the infinite loop.
So I gues my question is that does anyone know of a reason why the 6th step is not rendering and based on the given environment, can you guess what might be wrong here ?
I have seen and tried all the results that came in google relating to this matter, but nothing worked. I am not sure what is it that I am doing wrong. Also if there are any other methods to download a file, other than JSF, I will be happy to try them too.
Thanks in advance. :)
My Environment is:
- JSF 2.2
- Icefaces Ice and Ace
- Spring
- Hibernate 3
- Java Run Environment 1.5