Невозможно передать аргументы методу через EL - javax.el.MethodNotFoundException - PullRequest
1 голос
/ 10 января 2012

Используя JSF 2.0 и EL, я пытаюсь вызвать метод в POJO, который является атрибутом bean-объекта видимости. Код на самом деле очень похож на учебник @ BalusC здесь . Когда я вызываю метод, который не принимает аргументов, все нормально. Но когда я пытаюсь вызвать метод, который принимает аргумент, я получаю следующее исключение:

javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException:
/user.xhtml at line 42 and column 32 action="#{users.user.removeFriend(friend)}":
Method not found: model.User@67f2b0dd.removeFriend()

Вот еще несколько деталей:

user.xhtml

<f:metadata>
    <f:viewParam name="id" value="#{users.id}" />
    <f:event type="preRenderView" listener="#{users.init}" />
</f:metadata>

...

<h:form id="usersForm">
    <p:outputPanel>    
        <p:dataTable id="userTable" value="#{users.user.friendList}" var="friend">
            <p:column>
                <h:outputText value="#{friend.name}" />
            </p:column>
            <p:column>
                <p:commandButton action="#{users.user.removeFriend(friend)}"
                    ajax="true"
                    update="userTable somethingElse" process="@this"
                    onerror="errorDialog.show();"
                    icon="ui-icon-delete"
                    title="delete user">
                </p:commandButton>
            </p:column>
        </p:dataTable>
    </p:outputPanel>

    <p:commandButton action="#{users.user.removeAllFriends()}" ajax="true"
                update="userTable somethingElse"
                process="@this"
                icon="ui-icon-close"
                value="delete all friends?">
    </p:commandButton>


</h:form>

У меня есть следующий ViewScoped bean:

Users.java

@ManagedBean(name = "users")
@ViewScoped
public class Users implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;
    private User user;

    @ManagedProperty("#{userService}")
    private UserService userService; // session scoped

    public void init() {
        user = userService.getCart(id);
    }

    public final String getId() {
        return id;
    }

    public final void setId(String id) {
        this.id= id;
    }

    public final User getUser() {
        return user;
    }

    public final void setUser(User user) {
        this.user= user;
    }

    public final void setUserService(UserService userService) {
        this.userService = userService;
    }

}

Класс User - POJO - имеет атрибут private List<Friend> friends, с методами получения и установки и метод public User#removeFriend(Friend f). У него есть другой метод public; User#removeAllFriends().

Страница отображается нормально, но я получаю исключение, когда нажимаю кнопку «Удалить» рядом с пользователем в таблице.

Что здесь не так? Почему я могу успешно вызвать метод без параметров, но не могу передать аргументы другому?

Редактировать: Приложение развернуто на Tomcat 7.0, если это хорошо.

Любая помощь приветствуется.

Обновление: Как указали BalusC и Neo, это проблема с Tomcat 7.0. Я установил WebLogic 12.1 и все заработало.

Ответы [ 4 ]

7 голосов
/ 10 января 2012

Это ошибка в Tomcat.Он работает, когда вы вызываете метод для компонента напрямую, но не когда вы вызываете его для вложенного свойства.Я вспоминаю эту проблему как выпуск 50449 , о которой я когда-либо сообщал, но она была закрыта как «работает для меня» (возможно, они не проверяли ее должным образом, я не нашел в этом смысла спорить с Tomcatребята, у меня не было очень хорошего опыта с ними).В любом случае, я повторно сообщил об этом как выпуск 52445 с более надежным тестовым сценарием - я надеюсь.

Тем временем, заменяя реализацию EL на другую, от Glassfish дляНапример, должно получиться.Но я могу вам сказать, что все, что вы пытаетесь сделать, не совсем правильный подход.Вы объявили бизнес-метод в модели (класс сущности User) вместо контроллера (класс управляемых компонентов Users).Это неправильно.Модель должна использоваться исключительно для хранения данных.Контроллер должен использоваться для хранения бизнес-действий.

Я рекомендую переписать ваш случай следующим образом:

<h:form id="usersForm">
    <p:outputPanel>    
        <p:dataTable id="userTable" value="#{users.user.friends}" var="friend">
            <p:column>
                <h:outputText value="#{friend.name}" />
            </p:column>
            <p:column>
                <p:commandButton action="#{users.removeFriend(friend)}"
                    process="@this" update="userTable somethingElse" onerror="errorDialog.show();"
                    icon="ui-icon-delete" title="delete user" />
            </p:column>
        </p:dataTable>
    </p:outputPanel>

    <p:commandButton action="#{users.removeAllFriends}"
        process="@this" update="userTable numUsers"
        value="delete all friends?" />
</h:form>

и вместо этого поместить бизнес-методы в управляемый компонент Users:

public void removeFriend(Friend friend) {
    userService.removeFriend(user, friend);
    // ...
}

public void removeAllFriends() {
    userService.removeAllFriends(user);
    // ...
}

Также UserService, являющийся другим @ManagedBean, не совсем прав.На самом деле это должен быть @Stateless EJB, но это уже другая история.EJB все равно не поддерживаются в Tomcat, не обогащая его, например, OpenEJB .Без EJB необязательно должен быть другой управляемый компонент.Вы не хотите напрямую показывать эти сервисы.

1 голос
/ 17 ноября 2012

Если вы используете Tomcat, вы можете сделать следующее.

В xhtml файле вы делаете что-то вроде этого.

#{ItemInformationController.setFindItem(525)}
#{ItemInformationController.findItem}" var="AVar">

В вашем файле контроллера вы можете сделать что-то вроде этого:

int itemId;

public List<Item> getFindItem() {
    return getJpaController().findLevel3Item(levelId);
}

public void setFindItem(int id) {
    itemId= id;
}

Это работает с Tomcat 6/7 ...

1 голос
/ 10 января 2012

Ааа .. это объясняет это @ Tomcat .. Способ передачи параметра "# {users.user.removeFriend (friend)}" - это EL 2.2. Вы можете преодолеть это, выполнив следующие шаги: http://www.mkyong.com/jsf2/how-to-pass-parameters-in-method-expression-jsf-2-0/ ИЛИ используя другой способ, как описано здесь: http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/. Удачи!

0 голосов
/ 07 мая 2017
enter code here


@ManagedBean(name = "customerBean")
    @SessionScoped
    public class CustomerBean implements Serializable {
        /**/
        private static final long serialVersionUID = 1L;
        CustomerManager customerManager = CustomerManager.getInstance();


        private Book book;
        private Long id;
        private String name, vorname, addresse, ort;

        Customer customer = new Customer();
        ArrayList<Customer> customerList;

        public void findCustomer(String name){
            CustomerManager.getInstance().findCustomerByName(name);
        System.out.println("Hello" + customer.getName());

        }

    getters and setters...




     public class CustomerManager {
            static EntityManagerFactory emf;
            static EntityManager em;
            static CustomerManager instance;
            EntityTransaction entityTransaction = null;

            public CustomerManager() {
                emf = Persistence.createEntityManagerFactory("customerRegistration");
                em = emf.createEntityManager();
            }

            List<Customer> customerstList = new ArrayList<Customer>();
            Book book = new Book();
            Set<Book> bookList = new HashSet<Book>();

            Customer customer = new Customer();
    public void findCustomerByName(String name) {   
            // Query for a single object.
            Query query = em.createQuery("Select c FROM Customer c WHERE c.name = :name");
            query.setParameter("name", name);
            System.out.println("Hello from Business");
            customer = (Customer)query.getSingleResult();


                  }



    <ui:define name="content">
            <h:body>

                <h:form id="main">
                    <p:panelGrid columns="2">
                        <p:outputLabel for="name" value="#{texts.name}" />
                        <p:inputText id="name" value="#{customerBean.customer.name}" />


                        <h:commandButton value="Search"
                            action="#{customerBean.findCustomer()}" />
                    </p:panelGrid>
                </h:form>

            </h:body>
        </ui:define> 
...