ognl.OgnlRuntime.callAppropriateMethod中的MethodFailedException

时间:2011-05-02 18:49:38

标签: struts2 ognl

我有一个工作的Action和JSP表单,我用它在我的基本Struts 2.2.1.1应用程序中创建新实体。我正在尝试修改应用程序以重新使用相同的JSP表单来编辑实体。

我添加了一个“隐藏的”ID标签,现在我在提交表单时遇到错误。有人可以给我一些帮助吗?

我已经用Google搜索了这个问题并看到其他人发布了类似的错误,但我不确定如何解决它。

提交表单时摘自Stack Trace:

2011-05-02 11:09:36,132 3198497 ["http-bio-8080"-exec-23] WARN
com.opensymphony.xwork2.ognl.OgnlValueStack - Error setting expression
'id' with value '[Ljava.lang.String;@100ac03'
ognl.MethodFailedException: Method "setId" failed for object
org.robbins.flashcards.model.Tag@1b9eb34 [name='null' ]
[java.lang.NoSuchMethodException:
org.robbins.flashcards.model.Tag.setId([Ljava.lang.String;)]
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1285)
    at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:1474)

摘自JSP:

<%@ taglib prefix="s" uri="/struts-tags"%>
...
<s:form action="saveOrUpdateTag" method="post">
    <s:hidden name="id" />
    <s:textfield name="name" key="label.tag.name" size="20" />
    <s:submit label="label.flashcard.submit" align="center" />
</s:form>

摘自行动类:

public class TagAction extends FlashCardsAppBaseAction implements
ModelDriven<Tag> {

    Tag tag = new Tag();

    public Tag getTag() {
        return tag;
    }

    public void setTag(Tag tag) {
        this.tag = tag;
    }
    public String createTag() {
        ...
       }
}

摘自POJO:

public class Tag  implements java.io.Serializable {


     private int id;
     private String name;

    public int getId() {
        return this.id;
    }

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

摘自Struts.xml

    <action name="saveOrUpdateTag"
            class="org.robbins.flashcards.presentation.TagAction"
            method="createTag">
        <result name="success" type="tiles">displaytag.tiles</result>
        <result name="input" type="tiles">tagform.tiles</result>
    </action>

仅供参考 - 我还将此问题提交给Struts-User分发列表,但尚未收到任何输入,因此我也将在此处发布。当有更多信息可用时,我会更新其他帖子,反之亦然。

5 个答案:

答案 0 :(得分:9)

NoSuchMethodException ...([Ljava.lang.String;)]问题可能是由HTTP请求中具有相同名称的多个属性引起的。

如果具有相同名称的多个属性的情况是合法的,则可以通过将setId(int id)更改为setId(String [] idArray)并将每个数组成员字符串解析为整数来处理多个id值。

确保动作类中只有一个setId方法(setId(String [] idArray))。如果有多个方法具有相同的名称但参数类型不同,那么某些版本的struts / ognl(ognl 3.0.4?)可能会混淆。

例如:

public void setId(String[] idArray) {
    for (String idString : idArray) {
       int id = Integer.parseInt(idString);
       ... handle different id values somehow ...
    }
}

答案 1 :(得分:2)

值得注意的是,堆栈跟踪是警告,而不是错误。

此外,当表单字段实际填充了数字时,不会抛出警告。只有当它是空白时(或者假设它是用实际字符串填充的)才会抛出警告和堆栈跟踪。实际上,Action类的POJO模型上的Id字段成功填充了JSP表单字段值(如果存在)(以及一些过程)。

因此,我们可以忽略警告,因为它不会对我们造成任何伤害,或者将Id默认为某个数值,然后在我们的Action类中添加逻辑来处理它。

我决定忽略该警告,并相应地调整了我的log4j级别:

# Struts OgnlUtil issues unimportant warnings
log4j.logger.com.opensymphony.xwork2.util.OgnlUtil=error
log4j.logger.com.opensymphony.xwork2.ognl.OgnlValueStack=error

有关此主题的更详细讨论可以在Struts用户邮件列表中找到: http://mail-archives.apache.org/mod_mbox/struts-user/201105.mbox/%3CBANLkTinCzcTGjsn1jjotBr7fE_-5CX703w@mail.gmail.com%3E

答案 2 :(得分:0)

我猜这是一个老虫子。尝试升级到最新的Ognl版本。认为这可能是2.7。最新版本是在github上。在那里搜索,如果你想要非常确定,但2.7应该工作,我想。

答案 3 :(得分:0)

我认为这是隐藏的问题,如

这个, 如果您有两个页面,如果两个页面包含相同的隐藏名称,请在下面显示 你将得到一个ognl错误,删除1如果你在第一页保留隐藏的名称 并且您在第二页中使用的隐藏名称在第二页中删除(如果存在相同的隐藏名称)并且运行程序现在不会显示任何错误。 为什么它就像这意味着,可能我们已经隐藏在上一页中,并且可以在第二页中使用而不用隐藏,使用request.getParameter(“你的名字”); (这里隐藏变量重写)。 还有一个而不是给输入隐藏像输入类型隐藏,并给出名称和价值,这是我认为最好的。

  

答案 4 :(得分:0)

我也有同样的错误兄弟。但我不知何故找到了它 1.我们不需要为从jsp页面接受的输入字段定义getter setter,因为它是根据给定的名称自动映射的。 2.确保您传递的变量字段不应该是冗余的。 3.在我的情况下,我执行ajax调用传递一个字段(例如:userId)和提交表单(参数传递也有userId)。因此抛出错误。我把ajax调用参数的名称更改为(例如:userIdTemp),效果很好。