Last updated December 19, 2008 20:06, by Jason Lee
== <sc:download> - An Easy Way to Deliver Dynamic Content ==
The <code><sc:download></code> component offers a way to download or embed an arbitrary binary object, whether it's a dynamically generated image you would like to display on your web page, or a PDF-based report you'd like to download to your user. There are a number of ways to achieve this, from <code>Servlet</code>s to custom <code>PhaseListener</code>s. The problem with the Servlet approach is that it lives outside the JSF lifecycle, so there's a fair amount of work for the Servlet to do to force itself in. The <code>PhaseListener</code> approach, however, does live inside the JSF lifecycle, so it has immediate access to all that it needs. In fact, that's the approach <code>download</code> takes. The downside to the <code>PhaseListener</code> is the complexity involved in configuring the <code>PhaseListener</code>, managing the URI that triggers its code, and acquiring the resource requested.
The <code><sc:download></code> component, however, hides all of the from the page author. Take, for example, the use case in which you would like to load an image from the Classpath (or generate it on the fly), and display that to the user. You're code might look something like this:
<textarea name="code" class="xml"><nowiki>
public byte[] getImage() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
InputStream is = this.getClass().getClassLoader().getResourceAsStream("/sample.png");
int count = 0;
byte[] buffer = new byte[4096];
while ((count = is.read(buffer)) != -1) {
if (count > 0) {
baos.write(buffer, 0, count);
}
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
return baos.toByteArray();
}</nowiki></textarea>
To make use of that method from your web page, you would need something like this:
<textarea name="code" class="xml"><nowiki>
<sc:download mimeType="image/png" fileName="sample.png" data="#{testBean.image}">
<h:graphicImage url="#{downloadUrl}" width="250px" />
</sc:download></nowiki></textarea>
Note that the display of the image is actually done via the <code><h:graphicImage></code> component. The <code><sc:download></code> components defines, for any child components, an EL value which they can use to get the URL associated with the given resource. The default variable name, <code>downloadUrl</code>, can be changed if that happens to conflict with an variable already defined, as might happen inside a <code><h:dataTable></code>. To do so, simply provide the <code>urlVar</code> attribute:
<textarea name="code" class="xml"><nowiki>
<sc:download mimeType="image/png" fileName="sample.png" data="#{testBean.image}" urlVar="foo">
<h:graphicImage url="#{foo}" width="250px" />
</sc:download>
</nowiki></textarea>
If you would like to download the object to the user, you might try something like this:
<textarea name="code" class="xml"><nowiki>
<sc:download method="download" mimeType="application/pdf"
fileName="sample.pdf" data="#{testBean.pdf}">
<h:graphicImage alt="Download" url="/download.jpg"/>
</sc:download>
</nowiki></textarea>
Note the <code>method</code>. Here we specify that we want to download the object. We then specify the mime type and filename to use for the download. Note, also, the nested <code><h:graphicImage></code> component. This will be rendered as an anchor for the user to click to initiate the download. When clicked, the user will be asked to save the PDF names sample.pdf. It's as simple as that!





