无法通过 EL 将参数传递给方法 - javax.el.MethodNotFoundException [英] Cannot pass arguments to a method through EL - javax.el.MethodNotFoundException

查看:14
本文介绍了无法通过 EL 将参数传递给方法 - javax.el.MethodNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 JSF 2.0 和 EL,我试图在 POJO 上调用一个方法,POJO 是视图范围 bean 的一个属性.代码实际上与@BalusC的教程此处.当我调用一个不带参数的方法时,一切都很好.但是当我尝试调用一个带参数的方法时,我得到以下异常:

Using JSF 2.0 and EL, I am trying to call a method on a POJO which is an attribute of a viewscoped bean. The code is actually very similar to @BalusC's tutorial here. 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()

以下是更多详细信息:

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:

I have the following 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 ListFriends 属性,带有 getter 和 setter 以及一个 public 方法 User#removeFriend(Friend f).它有另一个 public 方法;User#removeAllFriends().

The User class - a POJO - has a private List<Friend> friends attribute, with getter and setters and a public method User#removeFriend(Friend f). It has another public method; 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?

该应用程序部署在 Tomcat 7.0 上(如果有的话).

The application is deployed on Tomcat 7.0, if that's any good.

感谢任何帮助.

更新: 正如 BalusC 和 Neo 所指出的,这是 Tomcat 7.0 的一个问题.我安装了 WebLogic 12.1,一切正常.

Update: As BalusC and Neo pointed, this is an issue with Tomcat 7.0. I installed WebLogic 12.1 and it all worked fine.

推荐答案

这是 Tomcat 中的一个错误.当您直接在 bean 上调用方法时它起作用,但当您在嵌套属性上调用它时不起作用.我记得这个问题是 issue 50449 我曾经报告过但已关闭因为对我有用"(也许他们没有很好地测试它,我觉得不值得再次与 Tomcat 的人争论,我和他们没有很好的经验).无论如何,我已将其重新报告为 issue 52445更可靠的测试用例 - 我希望.

This is a bug in Tomcat. It works when you call the method on the bean directly, but not when you call it on a nested property. 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). In any way, I have re-reported it as issue 52445 with a more solid testcase -I hope.

与此同时,将 EL 实现替换为不同的实现,例如 Glassfish,应该可行.但我可以告诉你,无论你尝试做什么,都不是真正的正确方法.您已经在模型(User 实体类)上而不是在控制器(Users 托管 bean 类)上声明了一个业务方法.这个不对.该模型应仅用于保存数据.控制器应该用于保存业务操作.

In the meanwhile, replacing the EL implementation with a different one, from Glassfish for example, should work out. 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). 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>

并将业务方法放在 Users 托管 bean 中:

and put the business methods in the Users managed bean instead:

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

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

此外,作为另一个 @ManagedBeanUserService 并不完全正确.它实际上应该是一个 @Stateless EJB,但那是另一回事.Tomcat 无论如何都不支持 EJB,而没有使用例如 OpenEJB 来丰富它.如果没有 EJB,它不一定需要是另一个托管 bean.您不想直接将这些服务公开到视图中.

Also the UserService being another @ManagedBean is not entirely right. It should actually be an @Stateless EJB, but that's another story. EJBs are not supported on Tomcat anyway without enriching it with for example OpenEJB. Without EJB, it does not necessarily need to be another managed bean. You don't want to expose those services into the view directly.

这篇关于无法通过 EL 将参数传递给方法 - javax.el.MethodNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆