The call of getter and setter methods by #{}
expressions is not part of JSF but Expression Language (most known as EL). JSF takes advantage of EL to bind the data of the HTML components to the fields of a bean through proper getters and setters. This is:
- If the bean exists, Expression Language will execute the proper getter of the registered bean in the proper scope.
- If client performs a form submission or an ajax request, then the components that are sent to the server (usually all the components in the
<h:form>
, in case of ajax requests you can state which components to send to the server) will contain a new value, and this value will be set to the field with the proper setter method.
For example, you have a SayHelloBean
which belongs to request scope:
@RequestScoped
@ManagedBean
public class LoginBean {
private String name;
//proper getter
public String getName() {
return this.name;
}
//proper setter
public void setName(String name) {
this.name = name;
}
}
And these 2 facelets pages (since it's an example I avoid declaring <html>
, <h:head>
, <h:body>
and other elements, just focusing on the relevant code)
Page1.xhtml:
<h:form>
Please tell me your name
<h:inputText value="#{loginBean.name}" />
<h:commandButton action="page2" />
</h:form>
Page2.xhtml:
Hello #{loginBean.name}
This is what happens behind the scenes:
When Page1.xhtml is loaded, a new instance of LoginBean
, which we may call loginBean
, will be created by JSF and registered into JSP request scope. Since the value of <h:inputText />
is bound to LoginBean#name
(which is read as the field name
of LoginBean
class), then EL will display the value of loginBean#name
(which is read as the field name
of instance loginBean
), and since that is not initialized, EL will display null
, as an empty string.
When you submit the form of Page1.xhtml, since LoginBean
is @RequestScoped
then JSF will create a new instance of LoginBean
, which we may call it loginBean2
(adding 2
in the end because this instance is totally different from the loginBean
previously created) and will register it in JSP request scope. Since the value of <h:inputText />
is bound to LoginBean#name
, JSF will validate and set the data by calling the proper setter. This will make loginBean2#name
have the value of the <input type="text">
that was rendered by <h:inputText/>
.
At last, JSF will make sure to navigate to Page2.xhtml through forward, where when processing it, it will find #{loginBean.name}
and EL will check for the value of loginBean2#name
and replace it.
The steps explained here are a very small explanation (and with lot of elements not explained) of the JSF lifecycle and how JSF uses getters and setters.
More info:
Additional note: since you're learning JSF, avoid putting any business logic code in getters/setters. This is greatly explained here: Why JSF calls getters multiple times
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…