(Yes, we would really need something to organize the posts and comments to these posts together. Once again, this started as commenting to a posted comment on the differences of servlet filters and PhaseListeners to my post on getting a reference to FacesContext, but then I realized my answer was getting a bit long, and decided to make it a blog post instead.)
A filter is really executing before the JSF lifecycle has started, i.e. before the faces context for that request has been set up, whereas in PhaseListener's case the faces servlet has the control on processing the request and has already created a faces context for that request. Now, regarding usage, a PhaseListener that would do its thing before RESTORE_VIEW phase would be more or less the same as using a filter before it calls doFilter() and passes the control over to another filter or the servlet. Likewise, a PhaseListener acting after RENDER_RESPONSE would be comparable to a filter that would modify the response after it has called doFilter().
The important difference is that PhaseListeners are part of JSF Lifecycle whereas filters are outside of it. Both have their own uses. Let's take a couple of examples to highlight what they are good for. One obvious usage for filters is authorization - you need to grant an access to different resources that are not served by the same servlet. If you don't want to use container based security for some reason or the other, e.g. if you want to use JAAS, filter based security is a natural choice. One other example might be a case where you need to support legacy software or devices. Say you have an old Struts app but you are gradually merging towards JSF. While you can get an access to the backing beans from the session, you might want to use the filter to invoke the JSF managed bean creation facilities to make sure that beans are created when you try to access them from the Struts code.
A watershed case might be supporting legacy devices I mentioned that can only generate GET requests. With filters, you can forward the request to a different end location and after pre-processing, reduce the problem to a normal JSF navigation case. Then again, if you do not need forwarding, but only a different way of passing parameters and populating backing bean properties, you might just as well use a JSF PhaseListener.
The perfect use case for PhaseListeners would be model2x rendering, i.e. applying XSL transformation to JSF output. The PhaseListener would transform the base JSF page to a form suitable for a specific client. There are lots of different options for XSL transformation in JSF as discussed in Sun's JSF forums (really interesting topic btw, but this is getting out of focus), but if you need to do XSL tranformation within the JSF lifecycle, a PhaseListener is the way to do it. I tried to think of a good example when to use a PhaseListener to modify a request, but couldn't think of any... anyone? I'll add it here if I hear about or figure out a good one.
I have a filter that I use to give Page's permission to the users. But there are some pages that I have two buttons named Change and Delete. So, how can I disable this two buttons within my filter and show the Page?
Posted by: Daniela at November 14, 2006 04:07 AM