我有一个工作的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分发列表,但尚未收到任何输入,因此我也将在此处发布。当有更多信息可用时,我会更新其他帖子,反之亦然。
答案 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),效果很好。