Listen and debug JSF lifecycle phases
The JSF lifecycle will be explained and debugged here. We'll also check what happens if you add immediate="true" to the UIInput and UICommand and what happens when a ConverterException and ValidatorException will be thrown.
The JSF lifecycle contains 6 phases:
- Restore view
- Apply request values
- Process validations
- Update model values
- Invoke application
- Render response
You can use a PhaseListener to trace the phases of the JSF lifecycle and execute some processes where required. But you can also use a "dummy" PhaseListener to debug the phases to see what is happening in which phase. Here is a basic example of such a LifeCycleListener:
package mypackage; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; public class LifeCycleListener implements PhaseListener { public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } public void beforePhase(PhaseEvent event) { System.out.println("BeforePhase: " + event.getPhaseId()); } public void afterPhase(PhaseEvent event) { System.out.println("AfterPhase: " + event.getPhaseId()); } }
Add the following lines to the faces-config.xml to activate the LifeCycleListener.
<lifecycle> <phase-listener>mypackage.LifeCycleListener</phase-listener> </lifecycle>
This produces like the following in the system output:
BeforePhase: RESTORE_VIEW 1
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: PROCESS_VALIDATIONS 3
AfterPhase: PROCESS_VALIDATIONS 3
BeforePhase: UPDATE_MODEL_VALUES 4
AfterPhase: UPDATE_MODEL_VALUES 4
BeforePhase: INVOKE_APPLICATION 5
AfterPhase: INVOKE_APPLICATION 5
BeforePhase: RENDER_RESPONSE 6
AfterPhase: RENDER_RESPONSE 6
Back to top
Basic debug example
To trace all phases of the JSF lifecycle, here is some sample code which represents simple JSF form with a fake converter and validator and the appropriate backing bean. The code sample can be used to give us more insights into the phases of the JSF lifecycle, to understand it and to learn about it.
The minimal contents of the test JSF file: test.jsp
taglib uri="http://java.sun.com/jsf/core" prefix="f" taglib uri="http://java.sun.com/jsf/html" prefix="h" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <f:view> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Debug JSF lifecycle</title> </head> <body> <h:form> <h:inputText binding="#{myBean.inputComponent}" value="#{myBean.inputValue}" valueChangeListener="#{myBean.inputChanged}"> <f:converter converterId="myConverter" /> <f:validator validatorId="myValidator" /> </h:inputText> <h:commandButton value="submit" action="#{myBean.action}" /> <h:outputText binding="#{myBean.outputComponent}" value="#{myBean.outputValue}" /> <h:messages /> </h:form> </body> </html> </f:view>
The fake converter: MyConverter.java
package mypackage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; public class MyConverter implements Converter { public Object getAsObject(FacesContext context, UIComponent component, String value) { System.out.println("MyConverter getAsObject: " + value); return value; } public String getAsString(FacesContext context, UIComponent component, Object value) { System.out.println("MyConverter getAsString: " + value); return (String) value; } }
The fake validator: MyValidator.java
package mypackage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; public class MyValidator implements Validator { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { System.out.println("MyValidator validate: " + value); } }
The backing bean: MyBean.java
package mypackage; import javax.faces.component.html.HtmlInputText; import javax.faces.component.html.HtmlOutputText; import javax.faces.event.ValueChangeEvent; public class MyBean { // Init ---------------------------------------------------------------------------------------- private HtmlInputText inputComponent; private String inputValue; private HtmlOutputText outputComponent; private String outputValue; // Constructors ------------------------------------------------------------------------------- public MyBean() { log("constructed"); } // Actions ------------------------------------------------------------------------------------ public void action() { outputValue = inputValue; log("succes"); } // Getters ------------------------------------------------------------------------------------ public HtmlInputText getInputComponent() { log(inputComponent); return inputComponent; } public String getInputValue() { log(inputValue); return inputValue; } public HtmlOutputText getOutputComponent() { log(outputComponent); return outputComponent; } public String getOutputValue() { log(outputValue); return outputValue; } // Setters ------------------------------------------------------------------------------------ public void setInputComponent(HtmlInputText inputComponent) { log(inputComponent); this.inputComponent = inputComponent; } public void setInputValue(String inputValue) { log(inputValue); this.inputValue = inputValue; } public void setOutputComponent(HtmlOutputText outputComponent) { log(outputComponent); this.outputComponent = outputComponent; } // Listeners ---------------------------------------------------------------------------------- public void inputChanged(ValueChangeEvent event) { log(event.getOldValue() + " to " + event.getNewValue()); } // Helpers ------------------------------------------------------------------------------------ private void log(Object object) { String methodName = new Exception().getStackTrace()[1].getMethodName(); System.out.println("MyBean " + methodName + ": " + object); } }
The minimal faces configuration: faces-config.xml
<converter> <converter-id>myConverter</converter-id> <converter-class>mypackage.MyConverter</converter-class> </converter> <validator> <validator-id>myValidator</validator-id> <validator-class>mypackage.MyValidator</validator-class> </validator> <managed-bean> <managed-bean-name>myBean</managed-bean-name> <managed-bean-class>mypackage.MyBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
Back to top
The first call
The first call in a freshly started webapplication with a fresh session should output at least:
BeforePhase: RESTORE_VIEW 1
AfterPhase: RESTORE_VIEW 1
BeforePhase: RENDER_RESPONSE 6
MyBean <init>: constructed
MyBean getInputComponent: null
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean getInputValue: null
MyBean getOutputComponent: null
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
As the UIViewRoot is empty, there is nothing to do in here.
2. Apply request values.
This phase is skipped because there is no form submit.
3. Process validations.
This phase is skipped because there is no form submit.
4. Update model values.
This phase is skipped because there is no form submit.
5. Invoke application.
This phase is skipped because there is no form submit.
6. Render response.
The bean is constructed. The components are created for the first time and stored in the UIViewRoot and set in the eventual component bindings. If the component binding getters returns precreated components (precreated in e.g. the constructor) and not null, then those will be used, otherwise JSF will create new components and set it in the eventual component bindings. The values to be shown are retrieved from the value binding getters in the backing bean. If the values aren't set yet, they defaults to null. The component bindings are not required by the way. Only use them if you actually need the component in the backing bean for other means than getting/setting the value. In this article they are included just to demonstrate what all happens in the lifecycle.
Back to top
The form submit
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
AfterPhase: PROCESS_VALIDATIONS 3
BeforePhase: UPDATE_MODEL_VALUES 4
MyBean setInputValue: test
AfterPhase: UPDATE_MODEL_VALUES 4
BeforePhase: INVOKE_APPLICATION 5
MyBean action: succes
AfterPhase: INVOKE_APPLICATION 5
BeforePhase: RENDER_RESPONSE 6
MyBean getInputValue: test
MyConverter getAsString: test
MyBean getOutputValue: test
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").
3. Process validations.
The submitted values are passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the initial input value differs from the submitted value, then the valueChangeListener method will be invoked.
4. Update model values.
The converted and validated values will now be set in the value binding setters of the backing bean. E.g. myBean.setInputValue(inputComponent.getValue()).
5. Invoke application.
The real processing of the form submission happens here.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.
Back to top
Add immediate="true" to UIInput only
Extend the h:inputText in the test.jsp with immediate="true":
...
<h:inputText
binding="#{myBean.inputComponent}"
value="#{myBean.inputValue}"
valueChangeListener="#{myBean.inputChanged}"
immediate="true">
...
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: PROCESS_VALIDATIONS 3
AfterPhase: PROCESS_VALIDATIONS 3
BeforePhase: UPDATE_MODEL_VALUES 4
MyBean setInputValue: test
AfterPhase: UPDATE_MODEL_VALUES 4
BeforePhase: INVOKE_APPLICATION 5
MyBean action: succes
AfterPhase: INVOKE_APPLICATION 5
BeforePhase: RENDER_RESPONSE 6
MyBean getInputValue: test
MyConverter getAsString: test
MyBean getOutputValue: test
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test"). The submitted values are immediately passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the initial input value differs from the submitted value, then the valueChangeListener method will be invoked. This all happens in this phase instead of the Process validations phase due to the immediate="true" in the h:inputText.
3. Process validations.
Nothing to see here. The conversion and validation is already processed in the Apply request values phase, before the values being put in the components. This is due to the immediate="true" in the h:inputText.
4. Update model values.
The converted and validated values will now be set in the value binding setters of the backing bean. E.g. myBean.setInputValue(inputComponent.getValue()).
5. Invoke application.
The real processing of the form submission happens here.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.
Back to top
Add immediate="true" to UICommand only
Extend the h:commandButton in the test.jsp with immediate="true" (don't forget to remove from h:inputText):
...
<h:commandButton
value="submit"
action="#{myBean.action}"
immediate="true" />
...
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
MyBean action: succes
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: RENDER_RESPONSE 6
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
The real processing of the form submission happens here. This happens in this phase instead of the Invoke application phase due to the immediate="true" in the h:commandButton. The UIInput components which don't have immediate="true" set will be ignored completely and therefore their values will not be converted and validated.
3. Process validations.
This phase is skipped due to the immediate="true" in the h:commandButton.
4. Update model values.
This phase is skipped due to the immediate="true" in the h:commandButton.
5. Invoke application.
This phase is skipped due to the immediate="true" in the h:commandButton.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean.
Take care: as the Update model values phase is skipped, the value bindings aren't been set and the value binding getters will return null. The UIInput components which don't have immediate="true" set will be ignored completely and therefore you cannot retrieve the values from the component or value bindings anyway. They will all remain the original values.
Back to top
Add immediate="true" to UIInput and UICommand
Extend the h:inputText as well as the h:commandButton in the test.jsp with immediate="true":
...
<h:inputText
binding="#{myBean.inputComponent}"
value="#{myBean.inputValue}"
valueChangeListener="#{myBean.inputChanged}"
immediate="true">
...
<h:commandButton
value="submit"
action="#{myBean.action}"
immediate="true" />
...
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
MyBean action: succes
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: RENDER_RESPONSE 6
MyConverter getAsString: test
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test"). The submitted values are immediately passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the initial input value differs from the submitted value, then the valueChangeListener method will be invoked. This all happens in this phase instead of the Process validations phase due to the immediate="true" in the h:inputText. Finally the real processing of the form submission happens here. This happens in this phase instead of the Invoke application phase due to the immediate="true" in the h:commandButton.
3. Process validations.
This phase is skipped due to the immediate="true" in the h:commandButton.
4. Update model values.
This phase is skipped due to the immediate="true" in the h:commandButton.
5. Invoke application.
This phase is skipped due to the immediate="true" in the h:commandButton.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.
Take care: as the Update model values phase is skipped, the value bindings aren't been set and the value binding getters will return null. But the values are still available by the relevant components in the UIViewRoot. In this case you can retrieve the input value from inputComponent.getValue() in the action() method. The new input value is also available by the ValueChangeEvent in the inputChanged() method.
Back to top
Conversion error
Let's see what happens if a conversion error will occur. Change the getAsObject() method of MyConverter.java as follows (and remove the immediate="true" from the test.jsp file):
package mypackage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; public class MyConverter implements Converter { public Object getAsObject(FacesContext context, UIComponent component, String value) { System.out.println("MyConverter getAsObject: " + value); throw new ConverterException("Conversion failed."); } ... }
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
AfterPhase: PROCESS_VALIDATIONS 3
BeforePhase: RENDER_RESPONSE 6
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").
3. Process validations.
The submitted values are passed through the converter getAsObject() method, where a ConverterException is thrown. The validator and the valueChangeListener are bypassed. Also the inputComponent.setValue(submittedValue) won't take place. The lifecycle will proceed to the Render response phase immediately.
4. Update model values.
This phase is skipped due to the ConverterException.
5. Invoke application.
This phase is skipped due to the ConverterException.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean, expecting the values for which a ConverterException has occurred. Behind the scenes those will be retrieved from the components in the UIViewRoot, e.g. inputComponent.getSubmittedValue().
Back to top
Validation error
Let's see what happens if a validation error will occur. Change the validate() method of MyValidator.java as follows (and remove the immediate="true" from the test.jsp file and revert MyConverter.java back to original):
package mypackage; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; public class MyValidator implements Validator { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { System.out.println("MyValidator validate: " + value); throw new ValidatorException(new FacesMessage("Validation failed.")); } }
The form submit with the value "test" entered should output at least:
BeforePhase: RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
AfterPhase: RESTORE_VIEW 1
BeforePhase: APPLY_REQUEST_VALUES 2
AfterPhase: APPLY_REQUEST_VALUES 2
BeforePhase: PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
MyValidator validate: test
AfterPhase: PROCESS_VALIDATIONS 3
BeforePhase: RENDER_RESPONSE 6
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
1. Restore view.
The bean is constructed. The components are restored in the UIViewRoot and set in the eventual component bindings.
2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").
3. Process validations.
The values are retrieved as objects from the components, passed through the converter getAsObject() method and validated by the validator, where a ValidatorException is thrown. The valueChangeListener is bypassed. Also the inputComponent.setValue(submittedValue) won't take place. The lifecycle will proceed to the Render response phase immediately.
4. Update model values.
This phase is skipped due to the ValidatorException.
5. Invoke application.
This phase is skipped due to the ValidatorException.
6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean, expect of the values for which a ValidatorException has occurred. Behind the scenes those will be retrieved from the components in the UIViewRoot, e.g. inputComponent.getSubmittedValue().
Back to top
Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.
(C) September 2006, BalusC

29 comments:
Thanks BalusC
It's give me good understanding inside JSF .
It's my sugestation that you start post your research on JavaWorld .
Thanks for you help on Sun forum .
With Thanks
Nice post, it helped me to clear JSF lifecycle a bit better. But I still have some doubts. :)
Why MyBean.getInputValue method is called twice, once in BeforePhase: PROCESS_VALIDATIONS and another in BeforePhase: RENDER_RESPONSE, in the form submit (without immediate on either UIInput and UICommand)?
One more thing, you could update the post with a calling to log method at MyBean's constructor. How many instances of a Managed Bean (scoped request) are created by a single JSF Request? This is something I still haven't understood in JSF Lifecycle.
I would be very thankful if you could answer.
Greetings from Brazil. :)
Mauricio
Why MyBean.getInputValue method is called twice
The first time is to compare the old submitted value with the new submitted value. If those values differs, then the valueChangeListener method will be invoked. The second time is just to display the new submitted value.
How many instances of a Managed Bean (scoped request) are created by a single JSF Request?
A request scoped bean is created only once per request. Just copy the code examples into your JSF playground and add a debug statement to the constructor yourself :)
Thanks for answering BalusC, I've been learning a lot reading your posts. :)
So, if there weren't any valueChangeListener in inputText the getIntputValue would be called just once in RENDER_RESPONSE. Is that it?
Ok, I'll add a debug statement in constructor for myself. But if more than one instance of MyBean are created per JSF Request, I'll be back! :)
Thank you one more time.
Mauricio
BalusC,
As others have said, thank you for this great posting. It helps me understand the JSF lifecycle a lot better.
I think that I could use a PhaseListener to check some other conditions and interrupt processing if they are not right. For example, let's say I want it to check user authorization. I have this class:
public class AuthorizationCheck implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
if (not userAuthorized()) {
//do something here, like...
//abort processing
//invoke an error view
}
}
public void afterPhase(PhaseEvent event){
return;
}
}
Since I'm pretty new to JSF, I don't know what to do for the "do something". How do I tell the lifecycle to start over with a different view that will show the user an error message?
You can invoke ExternalContext#redirect() to redirect the current request to a new request. It will "automatically" abort the JSF lifecycle as it implicitly calls FacesContext#renderResponse().
Thank you very much, that put me on the right track.
Hi BalusC:
I am in a situation where I need to implement a redirect from the construtor of a managedBean.
For instance :
Page 1 : Has a Name Search feature. Search results navigate to Page 2.
Page 2 : Has Extra information about the name based on DB querries from the DB in the page constructor. To Load data requried to display in Page2. There are hyperlinks on each information on this page that goes to the third Page. Once the information is worked, the related information linked to the name is removed from the DB and I will navigate to Page 2.
The problem that I am not able to resolve is, in the construtor of Page 2 when the DB queries donot return any more information on the name, I need to directly go to Page 1. How can I redirect from the contructor of the second page's specific backing bean.
I tried using Navigation Handler, and setting specific rootView. Netiher works when called from the constructor.
If I implement the PhaseListener, then would the pahse Listener logic be applied to all the other pages in the application ?
Please advice.
Thanks,
Sudeep
I got a work around by using sendRedirect("destinationPage"); in the constructor, however I am not too sure if using sendRedirect or forward is a good practice in JSF.
Could you please advice !
Its really a nice post, which gives the clear understanding of JSF Life Cycle.
All these days I was little confused with the immediate attribute, now its cleared.
Thanks BalusC.
Hi BalusC, great post!
Well, your sample has been performed on JSF1.1, right? Because I'm running your sample on JSF1.2 e I'm getting another result when i perform a "refresh" of the page, in fact, i get the same result from the "first call" to "refresh":
BeforePhase: RESTORE_VIEW 1
AfterPhase: RESTORE_VIEW 1
BeforePhase: RENDER_RESPONSE 6
MyBean getInputBinding: null
MyBean setInputBinding: javax.faces.component.html.HtmlInputText@187fafc
MyBean getOutputBinding: null
MyBean setOutputBinding: javax.faces.component.html.HtmlOutputText@6ecec5
MyBean getInputValue: null
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6
So, Did JSF1.2 change something in this aspect?
Thanks.
Wonderful Post, I use this site as a referance to just about anything to do with JSF.
One Question. I have a getter that calls a query in order to populate a datatable. Since under the normal lifecycle this getter is called in the APPLY_REQUEST_VALUES and the RENDER_RESPONSE does this not double the amount of calls to the Database?
How would you resolve this?
Thanks alot as your blog and when you hosted your site in the Netherlands really helped me out alot.
Just invoke that call only once per request. You can do this using the constructor or initialization block of a request scoped managed bean, or by introducing lazy loading in the getter.
Hello ,
I am working on a J2ee project where we are using JSF . Referring to your article where combination of UI Command Button and Immediate is stated .
I am using the combination of the two inorder to bypass the validations of non -immediate UI components on my form .
I am able to the bypass validations successfully , and subsequently the action method in my managed bean is also called and does some business logic and gets the response from the database ..
However subsequent to getting the response , the response should be populated on same JSF page . It is not getting populated on the same JSF page .
I have checked the mapping of attributes of JSF page and managed bean which is correct .
It would be really great and helpful , if you can please throw some light on this .
thanks ...
Please reply me on divya.prakash@gmail.com
Thanks for the explanation. I've a question: One of our action methods is not getting called. We saw the logs, but there's no exception anywhere. We tried putting the h:messages tag, but no errors were shown. We haven't put any validations and all our input fields are simple inputText fields that map to primitive values in the backing bean.
Based on your experience, would be going wrong?
@maverick-reuters: try using action dependent requireness instead of immediate.
@Parminder: assuming that all the phases of the JSF lifecycle are been processed; is the button/link been placed in a h:dataTable (or another iterated component) which obtains the list from a request scoped bean? If so, you need to ensure that it returns the same list in the next request.
No. The button isn't within a datatable. there's one thing different though. at runtime based on a property in the backing bean i include a page that contains a couple of components (drop down and a text box). please note that the button is not in the included jsp but the master page (the one that includes the other page).
Hi BalusC,
Thanks for your blog, it gave a very good understanding of the JSF lifecycle. It would be great if you help me out with a problem i am facing.
I am developing portlets with JSF framework. I am using Netbeans6.1 as IDE and Liferay 5.0.1 as the Portal container. The application runs on GlassfishV2 server. I am creating a simple application where i will display the name typed. However, the commandButton does not seem to call the action method in the corresponding managed bean. I have implemented a Lifecycle tracker. The logs show that instead of going thru all the lifecycles the application is going directly to Render_Response phase.
The button is within the f:view tag. i am unable to post sample codes of my jsp page. If u provide me a mail id i can mail u all the details.
if i deploy the application as a normal web application instead of a portlet application all the lifecycles are executed correctly.
Any help would be greatly appreciated.
Thanks
Hi balusc,
I am Ramu ur blog is excellent.
here i am having one problem.
I am using JAASActionListener for my security. i stored user object in a session. i wnt to retrieve that session i another backing bean. but i am gettng null value. please help me.
Thanks Ramu
Hello BalusC,
Wen i run this program, am receiving the following error..
Plz help me..
javax.servlet.ServletException: java.lang.LinkageError: loader constraints violated when linking javax/el/ExpressionFactory class
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:274)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
java.lang.LinkageError: loader constraints violated when linking javax/el/ExpressionFactory class
org.apache.jsp.index_jsp._jspInit(index_jsp.java:37)
org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
This has nothing to do with debugging JSF lifecycle.
Your classpath is just dirty.
Am using Eclipse3.3.1.1..
I included all necessary libraries..
Am able to run other JSF examples..
Then wr s d problem.. What i should change.. Am new to eclipse and JSF..
So pls help me..
I am using Spring JSF and got a form with validator for each component with some of the fileds have got required property as true.If I put a blank value in the required field it comes up with the validation error message , but subsequently when I put a valid value the data is saved and backing bean is updated correctly , but the page comes back with an empty value for that field.
I have checked each phase and it is passing the data correctly , but still JSF is showing a blank value . If I load the page again it shows me the correct value.
Any idea why it is doing ?
Hi, I have written two custom JSF validators for the same jsp, but only one of them is working. No sysouts from the other jsp are being displayed. The mapping in the faces-config.xml is correct. HeLP!!!
Hi, I have a command button on my JSF page to submit data to the server. After all the validation, I expect another page to be displayed. This process works as expected the first time. However, I find that the page just reloads itself on form submission the subsequent times (In other words, I have to click the submit button twice) for the other page to reload. I noticed that when the page reloads itself, only the Phases 1 and 6 are called instead of all the phases. Could you please help me out with this?
Hi BalusC, thank you so much for such a brilliant article which has cleared many of my doubts.
I have a problem in my jsf application, when ever there is a validation error, in the RenderResponse phase the getters for other components are also not called, its ok if the getter for the particular component whose validation has failed is not called but why other getters are also not called? am using jsf1.1
here is the log:
eforePhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O getEndOperTime********2359
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O falsejavax.faces.component.html.HtmlCommandButton
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O nameHtmlCommandButton
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O falsejavax.faces.component.html.HtmlForm
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O nameHtmlForm
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O inside onloadmode
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O requestMap:{atmoperationinformationsettings:_id48=SECOM, atmoperationinformationsettings:_id42=ATM/SC, atmoperationinformationsettings:_id37=Confirmation, atmoperationinformationsettings:_id62=SECOM, atmoperationinformationsettings:_id54=dd, atmoperationinformationsettings:_id58=2359, atmoperationinformationsettings=atmoperationinformationsettings}
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O mode1 Inside onloadMode of atmOperation:null
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
watch that getter which is being called at processValidations is not being called at renderResponse, wht cud be the reason, pls help me
and even if i try to reopen the page using a menubar in my application, it behaves differently
what i think whenever i click on a html link in my menu bar only restore view and renderresponse will get called, but see the log below which has executed all the phases jus for a request of a page, it is not a form submit right? but then why all the phases are executed?
O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O requestMap:{mode=atmOpeInfoSetting, frame=M}
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O mode1 Inside onloadMode of atmOperation:atmOpeInfoSetting
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O &&&&&&&&&&&&&&&&& atmOperation Id is called
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O &&&&&&&&&&&&&&&&& Transaction Id is 10040000028
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O Module is Loans!
[12/13/08 22:31:08:589 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
[12/13/08 22:31:08:589 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
Karthik ,
Hey , Its Divya !! .
About your second ambiguity :
Clicking of Menu : All the phases of JSF1.1. are called . I guess , just check the menu1.js (which controls how your page should be called) . I may be incorrect also , but I guess the code there seems to submit or reload the form again .. (that's why all the phases of jsf lifecycle are called ).
thanks
Great article! thank you. I have JFS button which generates report using jasper report. I want to update print date on the same page. But page does not update. I use HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); to generate output stream. Is it possible to force update page, after pressing button? Any ideas? Best regards Alex.
Excellent example explains life cycle of JSF nicely. Fantastic!!!!!
Post a Comment