I do not really understand how getter and setter work althougth it is a basic concept. I have the following code, how is the attribute id
sent to Managed Bean?
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:
<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
Whenever you use something like
#{someBean.someField}
the EL looks for a someBean.getSomeField() or someBean.setSomeField(...) method, depending on whether you're reading that field or writing in it (which can easily be inferred from the context). JSF never accesses a field directly (i.e without making use of its getter or setter). Try deleting the getter and setter of a given field and you'll see it won't work.