Create MethodExpression, содержащий метод с параметром типа Object, создает исключение синтаксического анализа

  • Я создаю MethodExpression напрямую через код Java.
  • Он будет представлять собой вызов метода bean-компонента с таким параметром, как follow .
#{bean.method(TheObjectInstance)}
  • Объект представляет собой простой настраиваемый объект pojo.
public class TheObject
{
   public String value0 = "value0";
}
  • Теперь мы создаем выражение MethodExpression, как показано ниже.
    TheObject object = new TheObject();

    FacesContext context = FacesContext.getCurrentInstance();
    Application application = context.getApplication();
    ExpressionFactory factory = application.getExpressionFactory();

    //Create method expression
    MethodExpression methodExpression = factory.createMethodExpression(
       context.getELContext(), 
       "#{bean.method(" + object + ")}", 
       null, 
       new Class<?>[] {TheObject.class});
  • Выдает следующую ошибку.
javax.servlet.ServletException: Encountered "@" at line 1, column 87.
Was expecting one of:
    "." ...
    "(" ...
    ")" ...
    "[" ...
    "," ...
    ";" ...
    ">" ...
    "gt" ...
    "<" ...
    "lt" ...
    ">=" ...
    "ge" ...
    "<=" ...
    "le" ...
    "==" ...
    "eq" ...
    "!=" ...
    "ne" ...
    "&&" ...
    "and" ...
    "||" ...
    "or" ...
    "*" ...
    "+" ...
    "-" ...
    "?" ...
    "/" ...
    "div" ...
    "%" ...
    "mod" ...
    "+=" ...
    "=" ...
  • Я попробовал тот же код со строковым параметром и логическим объектом, и он отлично работает, но использование пользовательского объекта также генерирует ту же ошибку, если мы передаем сложный объект, например, UIComponent.

  • Я использую JSF 2.2, любая помощь приветствуется.


person fra    schedule 14.05.2019    source источник
comment
Сделайте System.out.println(inputText) и посмотрите на результат. Вы пытаетесь пройти именно это. Почему это правильный синтаксис для компонента в качестве параметра? Сделать шаг назад. Сначала подготовьте доказательство концепции в простом ванильном XHTML-файле. Гораздо проще определить дерево компонентов и поведение в XHTML+XML. Как только вы поняли это, вы можете безопасно переписать код Java таким образом, чтобы он создавал точно такой же формат выражения (или просто придерживаться чистого XHTML, потому что эта привязка Java и все остальное довольно плохая практика и делает код трудным для чтения и поддерживать).   -  person BalusC    schedule 14.05.2019
comment
@BalusC Спасибо за ваш ответ. На самом деле, я просто хочу, чтобы commandButton принимал в качестве параметра actionListener компонент html, чтобы он исчезал при нажатии. Что-то вроде этого ‹h:commandbutton actionlistenner=#{bean.editMode(htmlComponent)} затем в методе editMode (компонент HtmlComponent) {component.render(false);}. С помощью этого кода я попробовал простой тестовый пример для параметра String/Boolean/List. Все работает, но этот HtmlElement не работает и генерирует ошибку, которую я вам показал. Это не расширенный код, поэтому я не уверен, что происходит. Ошибка исходит от MethodExpression.   -  person fra    schedule 14.05.2019
comment
@BalusC на самом деле, если я не использую Html, потому что это особый случай, я хочу создать пользовательскую общую таблицу данных, которая адаптируется к bean-компоненту и объекту сущности, который мы передаем в качестве параметра. поэтому нет выбора, кроме как делать общий код Java, а не чистый HTML. :(   -  person fra    schedule 14.05.2019
comment
Нет ничего невозможного в XHTML и возможного только в Java.   -  person BalusC    schedule 15.05.2019
comment
@BalusC Я отредактировал свой вопрос, чтобы упростить проблему и понять, где именно находится проблема. Сталкивались ли вы с проблемой такого типа при создании MethodExpression для метода bean-компонента с объектом в качестве параметра, подобного этому #{bean.method(myObject)}.   -  person fra    schedule 15.05.2019
comment
Сделайте System.out.println(object) и посмотрите на результат. Вы пытаетесь пройти именно это. Почему это правильный синтаксис для объекта в качестве параметра? Сделать шаг назад. Сначала подготовьте доказательство концепции в простом ванильном XHTML-файле. Гораздо проще определить дерево компонентов и поведение в XHTML+XML. Как только вы поняли это, вы можете безопасно переписать код Java таким образом, чтобы он создавал точно такой же формат выражения (или просто придерживаться чистого XHTML, потому что эта привязка Java и все остальное довольно плохая практика и делает код трудным для чтения и поддерживать).   -  person BalusC    schedule 16.05.2019
comment
@BalusC спасибо за ваш ответ. Вы заставляете меня понять, что есть лучший способ добиться этого, но мой вопрос не о том, что является лучшей практикой. Мой вопрос явно касается передачи объекта в качестве параметра выражения метода, подобного этому #{bean.method(myObject)}. Но у меня такое ощущение, что JAVA не поддерживает эту базовую функциональность, я прав?   -  person fra    schedule 16.05.2019
comment
@BalusC Я только что попробовал еще раз, теперь передавая список MyObject в качестве параметра MethodExpression, и он отлично работает, почему передача самого объекта не работает? сгенерированная ошибка очень сбивает с толку и не дает хорошего представления о том, что на самом деле происходит? Теперь, если это невозможно в JAVA, я предпочитаю иметь простой ответ, говорящий об этом, так что, по крайней мере, я знаю.   -  person fra    schedule 16.05.2019
comment
@BalusC также при использовании Datatable вы можете использовать var=entity в качестве параметра метода, вызываемого actionalistenner commandbutton, например #bean.method(entity)} сигнатура метода в bean-компоненте является общедоступным недействительным методом (объект EntityType ). Так что делать это через DataTable нормально, но делать это вручную, создавая MethodExpression через код JAVA, нельзя?   -  person fra    schedule 16.05.2019
comment
В примере с таблицей данных вы бы создали MethodExpression с "#{bean.method(entity)}", а не "#{bean.method(" + entity + ")}", верно? Потому что в обычном файле XHTML это действительно entity, а не com.example.Entity@12345678.   -  person BalusC    schedule 17.05.2019
comment
@BalusC спасибо. Я понимаю, что при передаче объекта напрямую в виде строки объект преобразуется с помощью метода класса toString и приводит к возврату подписи строки объекта com.example.Entity@12345678. Вот почему мы получаем ошибку Encounter @ в строке 1. Если я хочу, чтобы это работало, я должен использовать имя переменной в качестве параметра нашего выражения метода. Как и в случае с DataTable, мы объявляем var=entity, после чего можем использовать его в выражении EL для представления объекта.   -  person fra    schedule 18.05.2019
comment
@BalusC большое спасибо за терпение и попытку объяснить. Я согласен с вами, что этот случай можно упростить, используя XHTML с некоторой переменной в таблице данных и во время генерации столбцов/строк. Большое спасибо за ваши усилия.   -  person fra    schedule 18.05.2019


Ответы (1)


  • Чтобы создать MethodExpression с методом компонента, содержащим объект в качестве параметра #{bean.method(object)}, мы должны использовать имя переменной, объявленной на странице HTML var=object.
    <h:form>
     <h:datatable var="object" value="#{bean.objects}">
      <h:commandbutton value="test" actionlistenner="#{bean.method(object)}"/>
    </h:datatable>
    </h:form>
  • Если мы хотим сгенерировать одно и то же выражение MethodExpression #{bean.method(object)}, нам придется сгенерировать полные элементы html, включая родительский элемент html, в нашем случае таблицу данных, содержащую ссылку на объект var=object, а затем в коде выражения MethodExpression
    //Wrong implementation: the object is converted as object.getClass().toString()
    MethodExpression methodExpression = factory.createMethodExpression(
       context.getELContext(), 
       "#{bean.method(" + object + ")}", 
       null, 
       new Class<?>[] {TheObject.class});

    //Right implementation: we refer to object referenced by the datatable var. 
    MethodExpression methodExpression = factory.createMethodExpression(
       context.getELContext(), 
       "#{bean.method(object)}", 
       null, 
       new Class<?>[] {TheObject.class});
person fra    schedule 17.05.2019