简体   繁体   English

无法通过EL将参数传递给方法-javax.el.MethodNotFoundException

[英]Cannot pass arguments to a method through EL - javax.el.MethodNotFoundException

Using JSF 2.0 and EL, I am trying to call a method on a POJO which is an attribute of a viewscoped bean. 使用JSF 2.0和EL,我试图在POJO上调用方法,该方法是视域bean的属性。 The code is actually very similar to @BalusC 's tutorial here . 该代码实际上是非常相似的@BalusC的教程在这里 When I call a method that takes no arguments, everything's fine. 当我调用不带参数的方法时,一切都很好。 But when I try to call a method that takes an argument, I get the following exception: 但是,当我尝试调用带有参数的方法时,出现以下异常:

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()

Here are some more details: 以下是更多详细信息:

user.xhtml 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>

I have the following ViewScoped bean: 我有以下ViewScoped bean:

Users.java 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;
    }

}

The User class - a POJO - has a private List<Friend> friends attribute, with getter and setters and a public method User#removeFriend(Friend f) . User类-POJO-具有private List<Friend> friends属性,带有getter和setter以及public方法User#removeFriend(Friend f) It has another public method; 它有另一种public方法。 User#removeAllFriends() . User#removeAllFriends()

The page renders fine but I get the exception when I click the "Remove" commandButton next to a user in the table. 该页面呈现良好,但单击表中用户旁边的“删除”命令按钮时出现异常。

What's wrong here? 怎么了 Why can I successfully call a parameter-less method but can't pass arguments to another? 为什么我可以成功调用无参数方法但不能将参数传递给另一个方法?

Edit: The application is deployed on Tomcat 7.0, if that's any good. 编辑:如果可以的话,将应用程序部署在Tomcat 7.0上。

Any help appreciated. 任何帮助表示赞赏。

Update: As BalusC and Neo pointed, this is an issue with Tomcat 7.0. 更新:正如BalusC和Neo指出的,这是Tomcat 7.0的问题。 I installed WebLogic 12.1 and it all worked fine. 我安装了WebLogic 12.1,一切正常。

This is a bug in Tomcat. 这是Tomcat中的错误。 It works when you call the method on the bean directly, but not when you call it on a nested property. 当您直接在Bean上调用该方法时,它起作用,但在嵌套属性上调用时,则无效。 I recall this issue as issue 50449 which I have ever reported but was closed as "works for me" (perhaps they did not test it very properly, I didn't find it worth the effort to argue with Tomcat guys again, I haven't had very good experiences with them). 我记得这个问题是我曾经报告过的问题50449 ,但是由于“对我有用 ”而被关闭(也许他们没有对它进行非常正确的测试,我觉得不值得再次与Tomcat家伙争论,我还没有这样做)与他们有很好的经验)。 In any way, I have re-reported it as issue 52445 with a more solid testcase -I hope. 无论如何,我已将其重新报告为52445,并带有更可靠的测试用例-我希望。

In the meanwhile, replacing the EL implementation with a different one, from Glassfish for example, should work out. 同时,应该用不同于Glassfish的方法替代EL的实现方案。 But I can tell you that whatever you're trying to do is not really the proper approach. 但是我可以告诉你,无论您想做什么,都不是正确的方法。 You've declared a business method on the model (the User entity class) instead of on the controller (the Users managed bean class). 您已经在模型( User实体类)上而不是在控制器( Users管理的Bean类)上声明了一种业务方法。 This is not right. 这是不对的。 The model should solely be used to hold the data. 该模型应仅用于保存数据。 The controller should be used to hold the business actions. 控制器应用于保留业务操作。

I recommend to rewrite your case as follows: 我建议按照以下方式重写您的案例:

<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>

and put the business methods in the Users managed bean instead: 并将业务方法放入“ Users管理” Bean中:

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

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

Also the UserService being another @ManagedBean is not entirely right. 另外,作为另一个@ManagedBeanUserService也不完全正确。 It should actually be an @Stateless EJB, but that's another story. 它实际上应该是@Stateless EJB,但这是另一个故事。 EJBs are not supported on Tomcat anyway without enriching it with for example OpenEJB . 如果不使用例如OpenEJB来丰富EJB,则无论如何在Tomcat上都不支持EJB。 Without EJB, it does not necessarily need to be another managed bean. 如果没有EJB,它不一定需要是另一个托管bean。 You don't want to expose those services into the view directly. 您不想直接将这些服务公开到视图中。

If you are using Tomcat you can do the following. 如果使用的是Tomcat,则可以执行以下操作。

In the xhtml file you do something like this. xhtml文件中,您可以执行以下操作。

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

In your controller file you can do something like this: 在您的控制器文件中,您可以执行以下操作:

int itemId;

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

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

This works find with Tomcat 6/7... 这可以在Tomcat 6/7中找到...

Ahh.. that explains it @ Tomcat.. The way in which you are passing the parameter "#{users.user.removeFriend(friend)}" is EL 2.2. 嗯.. @ Tomcat对此进行了解释。传递参数“#{users.user.removeFriend(friend)}”的方式是EL 2.2。 You can overcome that by following the steps here: http://www.mkyong.com/jsf2/how-to-pass-parameters-in-method-expression-jsf-2-0/ OR by using some other way as described here: http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/ . 您可以按照以下步骤克服该问题: 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/ Good luck! 祝好运!

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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM