JSF2.0, how commandButton knows which bean to send this
I am starting in JSF2, comming from spring mvc, so I have some doubts that I cannot find answers on Core JavaServer Faces v3
Like this one...
How can the tag h:commandButton
know which bean I am talking about ? I can only have one Bean per JSF page, is that it ? I am only giving it a msg.next which is a text from a i18n file.(quizbean is my bean)
<h:body>
<h:form>
<h3>#{msgs.heading}</开发者_如何学运维h3>
<p>
<h:outputFormat value="#{msgs.currentScore}">
<f:param value="#{quizBean.score}"/>
</h:outputFormat>
</p>
<p>#{msgs.guessNext}</p>
<p>#{quizBean.current.sequence}</p>
<p>
#{msgs.answer}
<h:inputText value="#{quizBean.answer}"/>
</p>
<p><h:commandButton value="#{msgs.next}"/></p>
</h:form>
The command button does not need to know this. All it generates is a HTML <input type="submit">
element. This is embedded in a HTML <form>
with an action URL pointing to the same URL as the page. There's further also the <input type="hidden" name="javax.faces.ViewState">
. Thanks to this field, JSF knows exactly what view you're submitting to. This view holds information about all inputs. This view knows that there's an <h:inputText value="#{quizBean.answer}" />
. The view knows the field name
of the generated HTML <input type="text">
element. JSF will get the submitted request parameter value by request.getParameter()
using this name and then update the answer
property of the current instance of quizBean
with this value.
Rightclick the page in your browser and choose View Source to see the JSF-generated HTML output. Put a breakpoint on ApplyRequestValuesPhase#execute()
and HtmlBasicRenderer#decode()
methods (assuming that you're using Mojarra not MyFaces) to track the gathering of submitted values for every UIComponent
in the view.
The bean has to be managed by JSF, then it will know which bean you are talking about.
e.g.
<f:param value="#{quizBean.score}"/>
Here, the bean quizBean
is a Managed-Bean
, managed by JSF.
And to make it a managed bean you to tell JSF about it by either using annotations as follows -
@ManagedBean(name="quizBean") //name is optional or you give your own name to the bean
@SessionScoped //tell JSF in which scope you want to keep your managedbean
public class QuizBean {
//....
Or by mentioning it as follows in the JSF configuration file (faces-config.xml
) -
<managed-bean>
<managed-bean-name>quizBean</managed-bean-name>
<managed-bean-class>com.pkg.QuizBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
//Older versions of JSF requires this where annotations do not work
//But if you are using JSF 2.0 then it's a lot better to use annotations
You can use more than one beans in a view (page).
If this is an example from Core Java Server Faces
, then read more carefully, it explains everything.
msgs
as far as I remember, refers to message bundle, declared in faces-config.xml.
As for your question how commandButton knows which bean to call
. In your example, the class name QuizBean, most likely correspond to the bean with the same name. That's enough for JSF 2.0. However, you could change that name by 2 methods:
1) If you use JSF managed beans, you should go like this:
@ManagedBean(name="quiz")
@ViewScoped
public class QuizBean { }
2) If you use CDI-beans you would do this:
@Named("quiz")
@RequestScoped
public class QuizBean {}
Remember that CDI-beans scope annotations come from package javax.enterprise.context. And JSF scopes are in the javax.faces.bean package. Do not mix them!
Update: Please refer to page 35 of the book Core Java Server Faces 3rd Edition for more details about your question and do not hurry to ask questions if you don't understand something right away.
精彩评论