Chapter 32. JBoss EL
Seam uses JBoss EL to provide an extension to the standard Unified Expression Language (EL). This provides several enhancements to the expressiveness and power of EL expressions.
32.1. Parameterized Expressions
Standard EL does not allow methods to be used with user-defined parameters, but JBoss EL removoes this restriction. For example:
<h:commandButton action="#{hotelBooking.bookHotel(hotel)}" value="Book Hotel"/>
@Name("hotelBooking") public class HotelBooking { public String bookHotel(Hotel hotel) { // Book the hotel } }
32.1.1. Usage
As in method calls from Java, parameters are surrounded by parentheses, and separated by commas:
<h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}" value="Book Hotel"/>
Here, the parameters
hotel
and user
will be evaluated as value expressions and passed to the bookHotel()
method of the component.
Any value expression can be used as a parameter:
<h:commandButton action="#{hotelBooking.bookHotel(hotel.id, user.username)}" value="Book Hotel"/>
When the page is rendered, the parameter names —
hotel.id
and user.username
—are stored, and evaluated as value expressions when the page is submitted. Objects cannot be passed as parameters.
Parameters must be available both when the page is rendered and when it is submitted. If the arguments cannot be resolved at page submission time, the action method will be called with
null
arguments.
You can also pass literal strings using single quotes:
<h:commandLink action="#{printer.println('Hello world!')}" value="Hello"/>
Unified EL also supports value expressions, which are used to bind a field to a backing bean. Value expressions use JavaBean naming conventions and expect a getter/setter pair. JSF often expects a value expression where only retrieval (get) is required (for example, in the
rendered
attribute), but many objects do not have appropriately named property accessors, or do not require parameters.
JBoss EL removes this restriction by allowing values to be retrieved using the method syntax. For example:
<h:outputText value="#{person.name}" rendered="#{person.name.length() > 5}" />
You can access the size of a collection in a similar manner:
#{searchResults.size()}
In general, any expression of the form
#{obj.property}
would be identical to the expression #{obj.getProperty()}
.
Parameters are also allowed. The following example calls the
productsByColorMethod
with a literal string argument:
#{controller.productsByColor('blue')}
32.1.2. Limitations and Hints
JBoss EL does have several limitations:
- Incompatibility with JSP 2.1 —JBoss EL cannot currently be used with JSP 2.1, because the compiler rejects expressions that include parameters. You will need Facelets if you want to use this extension with JSF 1.2. The extension works correctly with JSP 2.0.
- Use inside iterative components —Components like
<c:forEach />
and<ui:repeat />
iterate over a list or array, exposing each item in the list to nested components. This is effective if you are selecting a row with a<h:commandButton />
or<h:commandLink />
like so:@Factory("items") public List<Item> getItems() { return entityManager.createQuery("select ...").getResultList(); }
<h:dataTable value="#{items}" var="item"> <h:column> <h:commandLink value="Select #{item.name}" action="#{itemSelector.select(item})" /> </h:column> </h:dataTable>
However, if you want to use<s:link />
or<s:button />
you must expose the items as aDataModel
, and use a<dataTable />
(or equivalent from a component set like<rich:dataTable />
). Neither<s:link />
or<s:button />
submit the form, so they do not produce a bookmarkable link. An additional parameter is required to recreate the item when the action method is called. This parameter can only be added when a data table backed by aDataModel
is used. - Calling a
MethodExpression
from Java code —Normally, when aMethodExpression
is created, the parameter types are passed in by JSF. However, in a method binding, JSF assumes that there are no parameters to pass. With this extension, there is no way to know the parameter types prior to expression evaluation. This has two minor consequences:- When you invoke a
MethodExpression
in Java code, parameters you pass may be ignored. Parameters defined in the expression will take precedence. - Ordinarily, it is safe to call
methodExpression.getMethodInfo().getParamTypes()
at any time. For an expression with parameters, you must first invoke theMethodExpression
before callinggetParamTypes()
.
Both of these cases are exceedingly rare and only apply when you want to invoke theMethodExpression
by hand in Java code.