Pages

Monday, May 07, 2012

JSF 2 Tip of the Day: Learning the JSF Lifecycle with a PhaseListener

I have to do some JSF training in the next couple of weeks for some of the staff at the company where I work. The learning curve for JSF has often been called a vertical wall. In part this is due to the JSF Lifecycle. The JSF Lifecycle has a number of phases, and before and after each phase there is an extension point where we can intervene in the process using a PhaseListener.

Since the PhaseListener intercepts the process, you can use it to learn the phases. The PhaseListener below is an example of one that reports on all PhaseEvents. You should modify it to learn what occurs during each phase.

PhaseListenerImpl.java

Here is the output:
INFO: Before Phase: RESTORE_VIEW 1 invoked.
INFO: After Phase: RESTORE_VIEW 1 invoked.
INFO: Before Phase: APPLY_REQUEST_VALUES 2 invoked.
INFO: After Phase: APPLY_REQUEST_VALUES 2 invoked.
INFO: Before Phase: PROCESS_VALIDATIONS 3 invoked.
INFO: After Phase: PROCESS_VALIDATIONS 3 invoked.
INFO: Before Phase: UPDATE_MODEL_VALUES 4 invoked.
INFO: After Phase: UPDATE_MODEL_VALUES 4 invoked.
INFO: Before Phase: INVOKE_APPLICATION 5 invoked.
INFO: After Phase: INVOKE_APPLICATION 5 invoked.
INFO: Before Phase: RENDER_RESPONSE 6 invoked.
INFO: After Phase: RENDER_RESPONSE 6 invoked.

Sunday, May 06, 2012

JSF 2 Tip of the Day: JSF Page Redirection in PhaseListener

I needed to redirect a user to a login page the other day, and solved it using a PhaseListener. Subsequently, I had another need to do a page redirection based on a value in the HttpSession. I thought I would share the general idea of how to do it with you.

The PhaseListener allows us to take action at various integration points in the JSF lifecycle. The most likely place you will want to handle an internal redirection, is before the view is restored. We use the JSF NavigationHandler to do the work for us.

PageRedirectionPhaseListener.java

Saturday, May 05, 2012

JSF 2 Tip of the Day: Programmatic PhaseListener

I had a use case where I needed to use a PhaseListener programmatically. I had originally tried to use a faces-config.xml to add the listener. I encountered a problem with an ear file which contained a war that contained a space. When Weblogic expanded the ear file it could not find the faces-config.xml since the path from expanded ear file had a space. Unfortunately, the program had too many dependencies to change to remove the space. So I decided to inject it. I was quite surprised to find that there was no annotation for PhaseListener in JSF 2.1.

Undaunted, I decided to figure it out. Admittedly, after I figured it out, I searched on Google, but everyone who had posted a solution did not a good example , or it was not quite as elegant as mine. I believe.

Specifically, my use case was to provide programmatic login where I use a PhaseListener to determine if the user is authenticated before restoring the view. This particular use case means that I must have the PhaseListener injected prior to responding to any requests. Fortunately, the JSF 2 API makes it very easy to do this.

The basic design is as follows:
  1. Use a @ManagedBean(eager=true) annotation. The eager attribute forces the container to load the bean immediately rather than lazy loading.
  2. Use the @ApplicationScoped annotation. This will allow us to set the PhaseListener for the whole application.
  3. Create a method which has a @PostConstruct annotation. This will allow us to set the listener immediately following the constructor.
    Note: You will want to follow this design so that if there are any annotations, they will be processed prior to adding the PhaseListener.
  4. Add the listener in the @PostConstruct method.

The JSF 2 API does a great job of explaining, how to use the LifecycleFactory to get a reference to the Lifecycle object. This is the key to adding the PhaseListener. If you are an API developer, this is a great example of documentation for people who want to use your API.

Code

The code for the project was developed using NetBeans 7.1.2 using Apache Maven. The code can be found here: programmatic-phaselistener.zip

ApplicationBean.java