JSF 2: как передать действие, включающее в себя аргумент, который будет вызван, в вложенное представление Facelets (используя ui:include и ui:param)?

Это в основном продолжение этого ответа.

Я пытаюсь получить аргумент в вызове метода / действия (для кнопки удаления в списке / таблице данных).

Клиент:

<ui:include src="...">
  <ui:param name="acceptButtonBean" value="#{repoHome}" />
  <ui:param name="acceptButtonAction" value="removeIndividualDocument(#{doc.id})" />
</ui:include>

Sub view:

<h:commandButton value="Continue"
                 action="#{acceptButtonBean[acceptButtonAction]}" />
  ...
</h:commandButton>

Тем не менее, JSF терпит неудачу с исключением, говоря:

...yadda, yadda
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5) Caused by: javax.el.MethodNotFoundException: /subviews/remove-doc-clink-popup.xhtml @37,98 action="#{acceptButtonBean[acceptButtonMethod]}": Method not found: com.company.project.beans.RepoHome@34b183e7.removeExternalDocument(89)()
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    ... 31 more

Обратите внимание

....RepoHome@34b183e7.removeExternalDocument(89)()

Это не может работать таким образом. JSF, кажется, добавляет круглые скобки, несмотря ни на что.

Можно ли достичь по-другому, но все же с помощью вышеописанной техники? Если так, то как?

Если нет, то почему это не работает? Это указано? Это ошибка с Mojarra 2.0.x? Я не вижу проблем, чтобы опустить скобки в случае наличия других скобок...

Примечание. Я не ищу альтернативных решений, таких как использование f: param, f: attribute или f: setPropertyActionListener.

заранее спасибо

1 ответ

Решение

Это действительно не действительно EL. Вы не можете смешивать имена методов и аргументы в одной переменной. Это должно работать:

<ui:include src="...">
  <ui:param name="acceptButtonBean" value="#{repoHome}" />
  <ui:param name="acceptButtonAction" value="removeIndividualDocument" />
  <ui:param name="acceptButtonArgument" value="#{doc.id}" />
</ui:include>

с

<h:commandButton value="Continue"
    action="#{acceptButtonBean[acceptButtonAction](acceptButtonArgument)}" />

Обратите внимание, что это относится не только к JSF, но и к EL. Если бы это была ошибка или функция, вам нужно было бы прочитать спецификацию EL или сообщить об этом ребятам EL, а не JSF. JSF не виноват здесь. EL - это полностью автономный API, который JSF использует.


Обновление: оказывается, что он работает на Tomcat 7 (и, вероятно, любой другой контейнер с org.apache.el.* реализации), но не на Glassfish 3 (с com.sun.el.* реализация). Он не работает следующим образом при отображении страницы:

Caused by: javax.el.ELException: Error Parsing: #{p1[p2](p3)}
    at com.sun.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:174)
    at com.sun.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:191)
    at com.sun.el.lang.ExpressionBuilder.createMethodExpression(ExpressionBuilder.java:242)
    at com.sun.el.ExpressionFactoryImpl.createMethodExpression(ExpressionFactoryImpl.java:81)
    at org.jboss.weld.util.el.ForwardingExpressionFactory.createMethodExpression(ForwardingExpressionFactory.java:43)
    at org.jboss.weld.el.WeldExpressionFactory.createMethodExpression(WeldExpressionFactory.java:62)
    at com.sun.faces.facelets.tag.TagAttributeImpl.getMethodExpression(TagAttributeImpl.java:222)
    ... 63 more
Caused by: com.sun.el.parser.ParseException: Encountered "(" at line 1, column 9.
Was expecting one of:
        (*snip*)

Я проверил главу 1.19 спецификации EL 2.2:

 ValueSuffix      ::= ‘.’ Identifier MethodParameters?
                    | ‘[‘ Expression ‘]’ MethodParameters?          <-- Look here
 MethodParameters ::= '(' (Expression (‘,’ Expression )* )? ')'

и я довольно уверен, что Tomcat прав. Пришло время сообщить об ошибке мальчикам из Glassfish: GLASSFISH-17628.


Обновление 2: вы, похоже, на самом деле используете JBoss 7. Я не знаю, какой именно Tomcat 7 он использует, но я могу подтвердить, что могу воспроизвести вашу проблему с Tomcat 7.0.19; после нажатия кнопки происходит следующее:

Caused by: javax.el.MethodNotFoundException: /test.xhtml @22,62 action="#{p1[p2](p3)}": Method not found: com.example.Bean@2616aa35.submit(java.lang.String)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 24 more

Я использовал Tomcat 7.0.22, когда он успешно работал, поэтому он был исправлен где-то между Tomcat 7.0.20 и 7.0.22.

Другие вопросы по тегам