Вызывать прямые методы или методы с аргументами/переменными/параметрами в EL

Как я могу в JSF 2.0 вызывать прямые методы или методы с аргументами/переменными/параметрами в EL?

Например, получение размера списка в элементе EL:

<h:outputText value="#{bean.list.size()}" />

Или вызов метода действия с аргументами:

<h:commandButton value="edit" action="#{bean.edit(item)}" />

Это не работает в моей среде. Скорее всего, это не похоже на круглые скобки.

javax.el.ELException: анализ ошибок: # { bean.list.size()}
com.sun.el.parser.ParseException: Encountered "("

Ответ 1

В стандартном EL до EL 2.2 из Java EE 6 вы не можете напрямую ссылаться на такие методы, как: #{bean.method()} и не вызывать методы с аргументами вроде #{bean.method(arg1, arg2).

Если переход на совместимый с EL 2.2/Java EE 6 контейнер (Tomcat 7, Glassfish 3, JBoss AS 6 и т.д.) не является вариантом, и вы используете EL 2.1/Java EE 5 (Tomcat 6, Glassfish 2, JBoss AS 4 и т.д.), Тогда лучше всего установить JBoss EL. JBoss EL - это реализация, совместимая с EL 2.1, которая поддерживает те же функции, что и EL 2.2. Установка JBoss EL - это вопрос jboss-el.jar в /WEB-INF/lib и добавление следующего к web.xml, предполагая, с использованием Мохарры:

<context-param>     
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>   
</context-param>

Или, когда вы используете MyFaces:

<context-param>     
    <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>   
</context-param>

Альтернативой вашему конкретному случаю является использование JSTL fn:length:

<h:outputText value="#{fn:length(bean.list)}" />

Другой альтернативой является добавление getter к bean, который возвращает List#size() или в некоторых конкретных случаях пользовательскую функцию EL.


Обратите внимание, что вызов методов с аргументами в EL не является особенностью JSF 2.0. Это особенность EL 2.2. EL 2.2 является частью Java EE 6, частью которой является JSF 2.0. Таким образом, он похож на JSF 2.0, но это не так. JSF 2.0 обратно совместим с Servlet 2.5/EL 2.1, в котором отсутствует эта функция. С другой стороны, JSF 1.x теперь совместим с Servlet 3.0/EL 2.2, поэтому также можно использовать эту функцию в JSF 1.x, а затем использовать JBoss EL на Servlet 2.5/EL 2.1.

Ответ 2

Ответа на этот вопрос Arend очень хорошо, кроме части о вводе context-param для Mojarra: добавив, что web.xml действительно разбивает его на JBoss 7. Попробуйте использовать JBoss EL, не введя ничего в web.xml.

Ответ 3

Ответ BalusC верен, однако, когда вы используете maven, вы должны исключить транзитивную зависимость el-api 1.0 следующим образом:

<dependency>
    <groupId>org.jboss.seam</groupId>
    <artifactId>jboss-el</artifactId>
    <version>2.0.0.GA</version>
    <!-- exclude el-api 1.0 transitive dependency -->
    <exclusions>
        <exclusion>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>