Phaselistener renders an image,no more Servlet
Posted by cagataycivici on February 16, 2006
In my previous entry, I mentioned about the underestimated powers of jsf phase listeners and presented some cases demonstrating some of these in theory. The first two was well known ajax cases and the third one was a secret power:rendering an image. I had not tried the third solution when writing the entry but using the chart component as a test case I’ve done some coding and now I am presenting the results.
Well, the theory in practice worked fine, using a phaselistener instead of a seperate servlet, I was able to present the images in a page with no problem. In order to do it, I’ve done small changes, first of all I’ve deleted the servlet definition. That shows how much I believe in phaselistener approach:) Then created a phase listener and register it in the faces-config.xml. The last thing was to change the img source rendered by the component. Instead of a servlet request, a faces request is used now;
<img src=”/servlet/Chartlet?id=chart1″ />
<img src=”faces/chartlistener?id=chart1″ />
The new img src is handled by the faces servlet which initiates the jsf lifecycle, after restore view phase when the view id is set, chartlistener takes the scene and by changing the response type to image/png or image/jpg or whatever, responses an image.
So why using a phaselistener instead of a servlet is necessary in this case and why do I do that?
# I wondered the possibility actually, it seemed to be a cool idea instead of an old-school servlet solution.
# Now no need to declare a servlet, instead a component user needs only the jar file.(Plug and Play)
# Servlet does not allow the portlet integration, now it is possible.
Here is a general example of this approach, the image is in hex format and phaselistener renders it to the client.
public class ImagePhaseListener implements PhaseListener { |
In order to let the phaselistener to do it’s job we have to refer the source of the image as;
<h:graphicImage value=”/hex_image.jsf” /> or <h:graphicImage value=”faces/hex_image />
Phaselisteners can respone anything actually, this was an example of an image rendering, you just need to change the response type and send the output to the client. Anyway I will use this approach when dealing with the next release of the JSF Chart Creator since the component is more pluggable this way. As Matthias commented to my previous entry: “PhaseListeners are great for developers, YES!”.

February 16, 2006 at 6:47 pm
yeah! cool, sounds great!

so… let’s get rid of non asf compliant licenses
February 16, 2006 at 7:21 pm
Yes Matthias, I wish there a is way around, that license issue is really annoying.
April 7, 2006 at 6:17 pm
Hi,
can you explain me your solution? I want to render an image with a Phase-Listener as you, but i didn’t found yur sourcecode. I have written a Phase-Listener and i have an Image-Hex-String. How can i render that Hex-String into an image with a Phase-Listener? It would be very nice if you can explain me that - i tried to implement that since 2 weeks…
My Listener is invoked at RENDER_RESPONSE and it doens’t work…
My afterPhase
public void afterPhase(PhaseEvent e) {
log.info(”AFTER ” + e.getPhaseId());
FacesContext context = null;
context = e.getFacesContext();
byte[] bytes = “FFD8F…myHexString”.getBytes();
ResponseStream rw = context.getResponseStream();
try {
rw.write(bytes,0,bytes.length);
} catch (IOException er) {
log.error(”Error while writing Image”);
er.printStackTrace();
}
}
April 23, 2006 at 6:40 pm
I’ve updated the entry and demonstrate how to render an image in hex format.
June 2, 2006 at 7:38 pm
That’s brilliant. As I have the image in database, I have no need to convert from hex. The rest is exactly what I needed. Thanks for this article.
September 24, 2006 at 5:16 am
good job!
But I don’t know how to apply the PhaseListner class to only one page not looked by other page!