使用JSF 2.0和EL,我试图在POJO上调用方法,该方法是视域bean的属性。该代码实际上是非常相似的
我调用不带参数的方法时,一切都很好。但是,当我尝试调用带有参数的方法时,出现以下异常:
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>
我有以下ViewScopedbean:
ViewScoped
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属性,具有吸气剂和setter和public方法User#removeFriend(Friendf)。它有另一种public方法。User#removeAllFriends()。
User
private List<Friend>friends
public
User#removeFriend(Friendf)
User#removeAllFriends()
该页面呈现良好,但单击表中用户旁边的“删除”命令按钮时出现异常。
怎么了 为什么我可以成功调用无参数方法但不能将参数传递给另一个方法?
编辑: 如果可以的话,将应用程序部署在Tomcat 7.0上。
任何帮助表示赞赏。
更新: 正如BalusC和Neo指出的,这是Tomcat 7.0的问题。我安装了WebLogic 12.1,一切正常。
这是Tomcat中的错误。当您直接在Bean上调用该方法时,它起作用,但在嵌套属性上调用时,则无效。我记得这个问题是我曾经报告过的问题50449,但是由于“对我有用 ”而被关闭(也许他们没有对它进行非常正确的测试,我觉得不值得再次与Tomcat家伙争论,我还没有这样做)与他们有很好的经验)。无论如何,我已将其重新报告为52445,并带有更可靠的测试用例- 我希望。
同时,应该用不同于Glassfish的方法替代EL的实现方案。但是我可以告诉你,无论您想做什么,都不是正确的方法。您已经在模型(User实体类)上而不是在控制器(Users托管Bean类)上声明了业务方法。这个不对。该模型应仅用于保存数据。控制器应用于保留业务操作。
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托管bean中:
public void removeFriend(Friend friend) { userService.removeFriend(user, friend); // ... } public void removeAllFriends() { userService.removeAllFriends(user); // ... }
同样,UserService另一个人@ManagedBean也不是完全正确的。它实际上应该是@StatelessEJB,但这是另一回事了。如果不使用例如OpenEJB来丰富EJB,则无论如何在Tomcat上都不支持EJB。如果没有EJB,它不一定需要是另一个托管bean。您不想直接将这些服务公开到视图中。
UserService
@ManagedBean
@Stateless