JSF 2.0 - Bookmarability/View Parameters

This seems to be one of the top features users have been requesting for JSF 2.0.  For those of you not reading the specification revisions as it has been published, the feature is available.

Bookmarkability is achieved using two new components:
  • h:link
  • h:button
Both of these components will generate a URL based on the specified navigation outcome.  Keep in mind, that in JSF 2.0, implicit navigation is available, so this outcome can be defined within the view or using standard navigation rules.

So, let's start with a simple example using one of these new components with implicit navigation.  Please note that the following examples assume that the FacesServlet is mapped to '\*.xhtml'.
    <h:link outcome="viewEntry" value="Link">
        <f:param name="entryName" value="#{someBean.entry}"/>
    </h:link>
In the example above, outcome, again, is the result of the navigation.  In this case, since we're assuming no navigation rules have been defined in the faces-config.xml, we're navigating to viewEntry.xhtml.  The f:param tag is adding a query parameter to the generated link.  When the component is rendered, the end result is something like:
<a href="http://localhost:8080/myapp/viewEntry.xhtml?entryName=entry1">Link</a>
The same can be achieved using navigation rules defined in the faces-config.xml.  For example:
<navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>redirectOutcome</from-outcome>
            <to-view-id>/page2.xhtml</to-view-id>
            <redirect>
                <view-param>
                    <name>entryName</name>
                    <value>#{someBean.value}</value>
                </view-param>
        </redirect>
    </navigation-case>
</navigation-rule>

Then reference the navigation outcome in one of the new components:
<h:link outcome="redirectOutcome" value="Link" />
which generates:
<a href="http://localhost:8080/myapp/page2.xhtml?entryName=entry1">Link</a>
Now, there's a third source of parameters that has been introduced in JSF 2.0 called 'View Parameters'.  These parameters are specified as metadata to the page and can be included in the generated URLs.  There's a lot more to view parameters than what is about to be shown.  I'll go more into that later on in this entry. 

Here's a simple example of a View Parameter (assume this is defined within somepage.xhtml):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
<head><title>somepage</title></head>
<body>
        <f:metadata>
            <f:viewParam id="id" name="viewParam" value="#{someBean.id}" />       
         </f:metadata>
         .
         .
</body>
</html>

If the developer sets the 'includeViewParams' attribute on h:link or h:button or the include-view-params attribute on the redirect element of a navigation-case to true, then the UIViewParameters will be a part of the generated URL.

So, building off of the metadata example above, consider the following h:link within another view:
<h:link outcome="sompage.xhtml" value="Link">
    <f:param name="componentParam" value="component"/>
</h:link>
The generated URL would look like:
<a href="http://localhost:8080/myapp/somepage.xhtml?componentParam=component&viewParam=view">Link</a>
Keep in mind that the view parameters that are included in the generated URL will be those of of the view being navigated to.

It's also important to note that there is an order of precedence for adding the parameters from the different sources.  This order is essentially, component, navigation-case parameters, followed by view parameters.  This means that if a component specifies a parameter via f:param that has the same name as that in a navigation-case or in the view metadata, then the parameter value from the navigation-case or view metadata will not be included in the query string.  

Now, getting back to view parameters, there's some other details I'd like to share.  In 1.2, the typical GET lifecycle would result in the restore view phase being invoked immediately followed by render response.  This is still true in 2.0 \*except\* when the view being processed has view parameters.  In this case, the view parameters are processed using the standard post-back processing lifecycle (i.e. apply request values,  process validations, update model, invoke application, then render response).   Processing view parameters in this fashion allows developers to attach converters and validators to the view parameters to enforce the integrity of the parameter data being passed to the view.  For example:

         <f:metadata>
            <f:viewParam id="id" name="id" value="#{newsReader.selectedStoryId}"
                     required="true"
                     requiredMessage="You did not specify an id. (The id parameter is missing)"
                     converterMessage="Invalid id. (The id parameter is not a number)"
                     validatorMessage="Invalid id. (The id parameter is not a positive number)">
                <f:validateLongRange minimum="1"/>
            </f:viewParam>       
         </f:metadata>


Lastly, developers need not restrict their usage of f:metadata to view parameters only.  Facelets templating features and view events (i.e. f:event) can also be specified.  One useage restriction of f:metadata needs to be kept in mind though - it must be defined within the view and not within a template.  If this restriction isn't observed, the content within f:metadata will not be processed.

That should cover the basics for now.  Please download the Mojarra 2.0.0 nightly and give this feature a shot.  Feel free to ask questions on the GlassFish Webtier forums, and if you think you found an issue, please let us know about it.

Comments:

Thanks..
This is good..

Posted by Himanshu on May 18, 2009 at 03:31 AM PDT #

Those features seams to be great, but I missed something in the GET parameter approach. After apply request values how the developer will trigger an action or an event like we have in Seam Page Actions?

Is there any annotations bind the request GET parameter values?

Posted by Marcos Sousa on May 19, 2009 at 01:59 AM PDT #

This is one of the most wanted feature after EzComp.

People have waited for this for too long

Great Job

Posted by Rahul on May 19, 2009 at 04:47 AM PDT #

This is still only a partial solution, but it's a good start. Long live PrettyFaces ;) yarrr

Posted by Lincoln Baxter III on May 19, 2009 at 07:15 AM PDT #

This is the feature what I waiting for. My question is:
How can I retrieve the view parameter values in bean?
Should use '{externalContext.requestMap}' ?
Thanks.

Posted by hivemind02 on May 19, 2009 at 10:50 AM PDT #

thanks

Posted by guest on May 19, 2009 at 04:55 PM PDT #

Really those new features from JSF 2 are good. Although I don't think be one good choice take out the .XML for navigation, because for maintenance is much easier just check the .XML file, than look for each .XHTML file. With .xml file all the navigation is centered in one place and without it, will be complicated and error prone keep going for all .xhtml files.
But is quite better than 1.2 version.

Posted by Klaus on May 20, 2009 at 11:51 AM PDT #

Hello Ryan,

"...would result in the restore view phase being invoked immediately followed by render response..." for which of the 2 views: the one pointed by the rendered link (page2.xhtml) or the one which rendered the <a...> link (page1.xhtml)?

Thanks.

Posted by Vlad on May 25, 2009 at 05:32 PM PDT #

[Trackback] Mojarra just went Beta, and the JSF spec just passed the JCP vote. If you haven't looked at JSF in a while, it's time to take another look.

Posted by Jim Driscoll's Blog on May 29, 2009 at 08:32 AM PDT #

Hello Ryan,
may I ask you how to use <h:link> for navigation to my controller servlet?
When I put path to controller servlet into outcome attribute, I get this warning:

com.sun.faces.renderkit.html_basic.OutcomeTargetRenderer getNavigationCase
WARNING: Navigation case not resolved for component j_id191899313_b70265b

Rendered view doesn't contain <a> tag, only closing one, like this:

<td><span>Detail</a></td>

Thanks in advance.

Posted by Jiri Huml on June 05, 2009 at 01:16 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

user12615560

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today