这是一件非常简单的事情,它与 Struts 2.1.x 完美配合。但是我们最近升级到 2.3.15.2 并且它坏了。基本上我们有一个包含多个提交的表单(实际上是很多表单):
<s:form>
<s:submit action="save" />
<s:submit action="resetPassword" />
</s:form>
如果我将动作粘贴在标签中,一切都很好。但如果它在标签中,我会收到 404 错误。而且是同一个动作!
我一直在调试,发现当你在标签中使用“action”属性时,生成的html是:
<input type="submit" name="action:save">
<input type="submit" name="action:resetPassword">
据说 Struts 应该使用这个“动作”前缀并说“啊哈!这是一个动作!” 并执行它。它或多或少是这样做的。或者至少尝试这样做。我发现,在非常低的级别上,DefaultActionMapper.handleSpecialParameters() 方法会遍历所有参数并尝试为每个参数创建一个 ParameterAction,如果它不为 null,则执行它。大多数参数产生一个“空”ParameterAction,但不是“action:”。
在文档中,我发现了有关 ParameterAction 的信息:
Defines a parameter action prefix. This is executed when the configured prefix key is
matched in a parameter name, allowing the implementation to manipulate the action mapping
accordingly. For example, if the "action:foo" parameter name was found, and a
ParameterAction implementation was registered to handle the "action" prefix, the execute
method would be called, allowing the implementation to set the "method" value on the
ActionMapping
所以它所做的就是将映射的结果设置为带有 Action 名称的新 ServletDispatcherResult:
mapping.setResult(new ServletDispatcherResult(actionName));
另一方面,当在 s:form 标记中指定操作时,映射的结果为空。
这样当我们最终到达 Dispatcher.serviceAction() 时:
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();
}
因此,当在标签中指定动作时,会调用 proxy.execute(),它只是调用动作/方法本身。这是应该发生的事情!但是当在标签中指定动作时,由于映射有结果,代理的调用被传递给 result.execute(),它调用 ServletDispatcherResult ...最后,我得到一个 404。
这似乎需要做很多工作才能让多个具有操作属性的提交按钮正常工作。这是 Struts 2.3 的已知问题吗?我是否需要为文档中所述的“action”前缀实现 ParameterAction?
编辑
好的,已知的错误,几天前才打开。与此同时,我可以降级到 2.3.15.1 或使用“method”属性而不是“action”属性。
希望它会尽快修复...