4.1.1.1. Page parameters

4.1.1.1. Page parameters

A JSF faces request (a form submission) encapsulates both an "action" (a method binding) and "parameters" (input value bindings). A page action might also needs parameters!

Since GET requests are bookmarkable, page parameters are passed as human-readable request parameters. (Unlike JSF form inputs, which are anything but!)

Seam lets us provide a value binding that maps a named request parameter to an attribute of a model object.

<pages>
    <page view-id="/hello.jsp" action="#{helloWorld.sayHello}">
        <param name="firstName" value="#{person.firstName}"/>
        <param name="lastName" value="#{person.lastName}"/>
    </page>
</pages>

The <param> declaration is bidirectional, just like a value binding for a JSF input:

The essential idea behind all this is that however we get from any other page to /hello.jsp (or from /hello.jsp back to /hello.jsp), the value of the model attribute referred to in the value binding is "remembered", without the need for a conversation (or other server-side state).

This all sounds pretty complex, and you're probably wondering if such an exotic construct is really worth the effort. Actually, the idea is very natural once you "get it". It is definitely worth taking the time to understand this stuff. Page parameters are the most elegant way to propagate state across a non-faces request. They are especially cool for problems like search screens with bookmarkable results pages, where we would like to be able to write our application code to handle both POST and GET requests with the same code. Page parameters eliminate repetitive listing of request parameters in the view definition and make redirects much easier to code.

Note that you don't need an actual page action method binding to use a page parameter. The following is perfectly valid:

<pages>
    <page view-id="/hello.jsp">
        <param name="firstName" value="#{person.firstName}"/>
        <param name="lastName" value="#{person.lastName}"/>
    </page>
</pages>

You can even specify a JSF converter:

<pages>
    <page view-id="/calculator.jsp" action="#{calculator.calculate}">
        <param name="x" value="#{calculator.lhs}"/>
        <param name="y" value="#{calculator.rhs}"/>
        <param name="op" converterId="com.my.calculator.OperatorConverter" value="#{calculator.op}"/>
    </page>
</pages>
<pages>
    <page view-id="/calculator.jsp" action="#{calculator.calculate}">
        <param name="x" value="#{calculator.lhs}"/>
        <param name="y" value="#{calculator.rhs}"/>
        <param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/>
    </page>
</pages>