JSF, Ajax and file download
Veröffentlicht in Montag, 31. März 2008 von Andreas Höhmann
Today i show you a example which combines Ajax (Richfaces) and a “normal” Download in a JSF application.
The bean for the download-code is here:
public class DownloadBean {
// actionListener="#{bean.execute}"
public void execute (ActionEvent event) {
download();
}
// action="#{bean.download}"
public String download() {
final FacesContext facesContext = FacesContext.getCurrentInstance();
// XXX create temp. filecontent ... resultFile
writeOutContent(getServletResponse(), new File(this.resultFile), "file.xml");
facesContext.responseComplete();
// dont use jsf-navigation-rules
return null;
}
void writeOutContent(final HttpServletResponse res, final File content, final String theFilename) {
if (content == null)
return;
try {
res.setHeader("Pragma", "no-cache");
res.setDateHeader("Expires", 0);
res.setContentType("text/xml");
res.setHeader("Content-disposition", "attachment; filename=" + theFilename);
fastChannelCopy(Channels.newChannel(new FileInputStream(content)), Channels.newChannel(res.getOutputStream()));
} catch (final IOException e) {
}
}
void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException {
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
while (src.read(buffer) != -1) {
buffer.flip();
dest.write(buffer);
buffer.compact();
}
buffer.flip();
while (buffer.hasRemaining()){
dest.write(buffer);
}
}
}
Now the facelets snipplets: Not Working - Javascript Error
<h:form>
<h:commandLink actionListener="#{command.execute}" value="Download"/>
<h:commandLink action="#{command.download}" value="Download"/>
</h:form>
Not Working - Download is shown in the current page - the ajax page will replaced with the download-content
<a4j:form>
<a4j:commandLink actionListener="#{command.execute}" value="Download"/>
<a4j:commandLink action="#{command.download}" value="Download"/>
</a4j:form>
Working
<a4j:form>
<a4j:htmlCommandLink actionListener="#{command.execute}" value="Download"/>
<a4j:htmlCommandLink action="#{command.download}" value="Download"/>
</a4j:form>
<h:form>
<a4j:htmlCommandLink actionListener="#{command.execute}" value="Download"/>
<a4j:htmlCommandLink action="#{command.download}" value="Download"/>
</h:form>
The a4j:htmlCommandLink was made for this szenario.
Notice: the fast channel copy routine was introduced by waffel.
Abgelegt unter : Computer, JSF | Getaggt: JSF, Facelets, Richfaces, Ajax, File Download, MyFaces