我正在通过查询字符串将一些参数传递给实现ModelDriven<Transporter>
的 Action 类。
<s:form namespace="/admin_side" action="Test" id="dataForm" name="dataForm">
<s:url id="editURL" action="EditTest" escapeAmp="false">
<s:param name="transporterId" value="1"/>
<s:param name="transporterName" value="'DHL'"/>
</s:url>
<s:a href="%{editURL}">Click</s:a>
</s:form>
Action 类如下。
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
public final class TestAction extends ActionSupport
implements Serializable, Preparable, ModelDriven<Transporter>
{
private static final long serialVersionUID = 1L;
private Transporter transporter = new Transporter();
@Action(value = "Test",
results = {
@Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
@InterceptorRef(value = "paramsPrepareParamsStack",
params = {"params.acceptParamNames", "transporterId, transporterName"})})
public String load() throws Exception {
return ActionSupport.SUCCESS;
}
@Action(value = "EditTest",
results = {
@Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
@InterceptorRef(value = "paramsPrepareParamsStack",
params = {"params.acceptParamNames", "transporterId, transporterName"})})
public String edit() {
System.out.println(transporter.getTransporterId()
+ " : " + transporter.getTransporterName());
return ActionSupport.SUCCESS;
}
@Override
public Transporter getModel() {
return transporter;
}
@Override
public void prepare() throws Exception {}
}
服务器终端显示以下消息。
Jan 09, 2014 4:06:32 PM com.opensymphony.xwork2.interceptor.ParametersInterceptor error
SEVERE: Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'transporterId' on 'class actions.TestAction: Error setting expression 'transporterId' with value ['1', ]
Jan 09, 2014 4:06:32 PM com.opensymphony.xwork2.interceptor.ParametersInterceptor error
SEVERE: Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'transporterName' on 'class actions.TestAction: Error setting expression 'transporterName' with value ['DHL', ]
即使日志级别为
SEVERE
,这些参数的值也可以在操作类中以System.out.println(transporter.getTransporterId()
+ " : " + transporter.getTransporterName());
在
edit()
方法中。如果将
paramsPrepareParamsStack
替换为defaultStack
,则这些消息将消失。像
['DHL', ]
这样的表达式表示一个数组。但是,模型中的transporterId
和transporterName
分别为Long
和String
类型。我究竟做错了什么?
最佳答案
这里不涉及数组问题(即使看起来像这样):这种异常意味着Struts找不到参数的Setter:
从ParametersInterceptor documentation:
通过将JSP中不存在的元素放入Action中,可以轻松地重现此错误。
由于您的属性在模型中存在(及其 setter ),并且您正在使用ModelDriven
和paramsPrepareParamsStack
,所以我认为是:
ModelDriven Interceptor
被委托(delegate)处理Model对象; Parameters Interceptor
时,ModelDriven Interceptor
尚未运行。 但是,如果这是真的,那么您应该 NOT 能够在
prepare()
方法中检索那些参数(这就是您使用此堆栈的原因...):请尝试,然后将结果发布在此处。解决此问题的第一件事是将
ModelDriven Interceptor
放在第一个Parameters Interceptor
之前(通过复制或移动它,我不确定它会产生哪种副作用(如果有)在这两种情况下,您都应再次尝试并在此处进行报告)。然后定义以下堆栈,并使用它。
<interceptor-stack name="modelParamsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<!-- NEW ModelDriven Position -->
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="params">
<param name="excludeParams">^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<!-- OLD ModelDriven Position -->
<!--interceptor-ref name="modelDriven"/-->
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
希望能有所帮助。