URL bookmarking refers to storing locally (in
your browser) the link from the browser address bar. This facilitate a quick
access to the bookmarked page.
Well, let's see
why this is an issue in JSF.
1. Consider that you have bookmarked a faces
link of type http://www.foodomain.org
This is not a problem for JSF.
2. Consider the same thing for this faces
link: http://www.foodomain.org?name=foo&email=buzz
The name and email request parameters values have been provided by a
managed bean during "exploring" the website (e.g. this link may be
the result of navigating via <h:link> and <f:param
name="name" value="#{myBean.name}"/> and
<f:param name="email" value="#{myBean.email}"/>). The problem is that this URL is not
eligible for bookmarking, because if you load it later in the browser then the
managed bean properties will not be initialized with these request parameters
values. This means that if somewhere in this page you need to use #{myBean.name} and/or #{myBean.email}
then they will not be foo and buzz.
This is
a job for the JSF view parameters!
They "carry" the request parameters values to their managed bean
properties (usually they do this, but is not mandatory to tied them up to a
managed bean). Moreover, because view parameters are basically UIInputs, we can
validate and convert the provided values before "hitting" the managed
beans. By converting the values we can obtain from plain strings complex data
(e.g. objects) and by validating the data, we ensure that the user provides
valid data in our model.
The managed bean properties should be
initialized as fast as possible since the current view may need them. But, at initial
request, JSF executes only the Restore View and Render Response phases, not the
Update Model Values phase. This means that JSF doesn't update the model at initial request, so the
question is how the managed beans gets updated?
Well, this is why we are using <f:metadata>!
This tag declares the metadata facet for this view and the content of this section
is readable without having the entire view available. Moreover, at the initial
request, components from this section can accomplish different things before
the view is rendered. The <f:metadata> force JSF to
execute all phases at initial request!
View parameters (<f:viewParam>)
are nested in the metadata section, and this section is processed by JSF before
the entire view is ready. The view parameters values are fetched from request
parameters during decoding (Apply Request Values phase), and hit the managed
bean in the Update Model Values phase. So, right before rendering phase (Render
Response) the bookmarked query string (?name=foo&email=buzz) reaches the model and is available during
rendering process!
This means that the data model is populated right
from the initial request with the values of the view parameters that are linked
to managed beans properties. This makes
faces URLs with query string to be eligible for bookmarking!
Think to a simple
case - somewhere in
the bookmarked page, you have something like #{myBean.name} where name should be initialized based on the above
request parameter (?name=foo). Now, you access by bookmark this, http://www.foodomain.org?name=foo.
This means that when the #{myBean.name}
is evaluated, the name property of the MyBean is null, not foo!
Further, we add a view parameter of type <f:viewParam name="name" value="#{myBean.name}"/>, but we don't add this in the metadata
section. Since JSF search view parameters only in metadata section, this will
not work also.
Finally, we add our view parameter in the
metadata section. Since the metadata section has "priority", JSF will
process it and will link the name view parameter with the name managed bean
property, before the #{myBean.name} is evaluated during rendering. This means
that #{myBean.name} is evaluated to foo.
The view parameters can be passed between views via:
- the ?faces-redirect=true&includeViewParams=true
query string attached to the target outcome in the action
attribute of the <h:commandButton>,
<h:commandLink>;
- the ?faces-redirect=true&includeViewParams=true
string attached to the target outcome returned by an action method pointed via <h:commandButton>, <h:commandLink>;
- the includeViewParams=true attribute explicitly attached
to the <h:link> or <h:button>;
- the OmniFaces
<o:form>
component which keep view or request parameters in the request URL after a
post-back and offers in combination with the <o:ignoreValidationFailed>
tag on an UICommand component the
possibility to ignore validation failures so that the invoke action phase will
be executed anyway.
Niciun comentariu :
Trimiteți un comentariu