意外异常在'类xxx上设置了'xxx':错误设置表达式'xxx',其值为['x',] [英] Unexpected Exception caught setting 'xxx' on 'class xxx: Error setting expression 'xxx' with value ['x', ]

查看:136
本文介绍了意外异常在'类xxx上设置了'xxx':错误设置表达式'xxx',其值为['x',]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一些参数传递给通过查询字符串实现 ModelDriven< Transporter> 的动作类。



< pre class =lang-xml prettyprint-override> < s:form namespace =/ admin_sideaction =Testid =dataFormname =dataForm>
< s:url id =editURLaction =EditTestescapeAmp =false>
< s:param name =transporterIdvalue =1/>
< s:param name =transporterNamevalue ='DHL'/>
< / s:url>
< s:a href =%{editURL}>点击< / s:a>
< / s:form>

行动类如下。

  @Namespace(/ admin_side)
@ResultPath(/ WEB-INF / content)
@ParentPackage(value = struts-default)
public final class TestAction extends ActionSupport
实现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());
返回ActionSupport.SUCCESS;
}

@Override
public Transporter getModel(){
return transporter;
}

@Override
public void prepare()throws Exception {}
}

服务器终端显示以下消息。

  2014年1月9日下午4:06:32 com.opensymphony.xwork2.interceptor.ParametersInterceptor错误
严重:开发人员通知(将struts.devMode设置为false以禁用此消息):
意外的异常捕获设置'transporterId'''class actions.TestAction:错误设置表达式'transporterId'的值['1',]
2014年1月9日下午4:06:32 com.opensymphony.xwork2.interceptor.ParametersInterceptor错误
SEVERE:开发人员通知(将struts.devMode设置为false以禁用此消息):
意外异常捕获设置'class actions.TestAction上的'transporterName':错误设置表达式'transporterName',其值为''DHL', ]

即使日志级别为 SEVERE ,这些参数的值在动作类中可用为

  System.out.println(transporter.getTransporterId()
+:+ transporter.getTransporterName());

edit()方法中的



如果 paramsPrepareParamsStack defaultStack 替换,则这些消息消失。



['DHL',] 等表达式表示一个数组。模型中的 transporterId transporterName ,但类型为 Long 字符串分别。



我做错了什么?

解决方案

此处不涉及任何数组问题(即使看起来像这样):这种异常意味着Struts无法为您的参数找到Setter:



来自 ParametersInterceptor文档


缺少参数的警告



给定的参数名称没有setter,下面的警告消息
将记录在devMode中:

  SEVERE:开发者通知(将struts.devMode设置为false以禁用此
消息):
意外异常捕获设置'搜索'开启' class demo.ItemSearchAction:
错误设置表达式'search',其值为''search',]
错误设置表达式'search',其值为['search',] - [unknown location]
at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:201)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:178)
at com.opensymphony .xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:152)

因此预期的行为是允许的开发人员在参数名称或setter中发现缺少setter
或拼写错误。


您可以轻松地通过放置一个错误来重现此错误JSP中不存在于Action中的元素。



由于您的属性(使用其Setter)存在于Model中,并且您使用的是 ModelDriven paramsPrepareParamsStack ,我认为现在的情况是:




  • ModelDriven Interceptor 被委托处理Model对象;

  • 第一次调用参数Interceptor ModelDriven Interceptor 尚未运行;

  • 然后你的Action对Model对象一无所知,并尝试在Action中找到参数的Setters,而不是在Model中。

  • 第二个拦截器改为在ModelDriven之后运行,并且确切地知道设置参数的位置。这就是你在Action方法中正确设置参数的原因。



但如果这是真的,那么你应该 NOT 能够在 prepare()方法中检索这些参数(这就是你使用这个堆栈的原因......):
请尝试,并在此处发布结果。



我想要解决此问题的第一件事就是放置 ModelDriven拦截器在第一个参数拦截器之前(通过复制或移动它,我不确定它会产生哪种副作用,如果有的话)在这两种情况下,你应该再次尝试在这里报告它。)



然后定义下面的堆栈,并使用它。

 < 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(要求|响应)\ .. *,^ parameters\ .. *,^动作:*,^方法:* LT; / 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(要求|响应)\ .. *,^ parameters\ .. *,^动作:*,^方法:* LT; / PARAM>
< / interceptor-ref>
< interceptor-ref name =conversionError/>
< interceptor-ref name =validation>
< param name =excludeMethods>输入,返回,取消,浏览< / param>
< / interceptor-ref>
< interceptor-ref name =workflow>
< param name =excludeMethods>输入,返回,取消,浏览< / param>
< / interceptor-ref>
< / interceptor-stack>

希望有所帮助。


I'm passing some parameters to an action class implementing ModelDriven<Transporter> through a query-string.

<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>

The action class is as follows.

@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 {}
}

The server terminal displays the following messages.

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', ]

Even though the log level is SEVERE, the values of these parameters are available in the action class as

System.out.println(transporter.getTransporterId() 
                 + " : " + transporter.getTransporterName());

in the edit() method.

If paramsPrepareParamsStack is replaced by defaultStack then, these messages disappear.

Expressions like ['DHL', ] indicate an array. transporterId and transporterName in the model are, however of type Long and String respectively.

What am I doing wrong?

解决方案

No array problem is involved here (even if it seems like that): this kind of exception means that Struts can't find a Setter for your parameter:

From ParametersInterceptor documentation:

Warning on missing parameters

When there is no setter for given parameter name, a warning message like below will be logged in devMode:

SEVERE: Developer Notification (set struts.devMode to false to disable this 
message):
Unexpected Exception caught setting 'search' on 'class demo.ItemSearchAction: 
Error setting expression 'search' with value ['search', ]
Error setting expression 'search' with value ['search', ] - [unknown location] 
  at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:201)
  at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:178)
  at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:152)

Thus is expected behaviour to allow developer to spot missing setter or typo in either parameter name or setter.

You can easily reproduce this error by putting an element in JSP that does not exist in the Action.

Since your properties exist (with their Setters) in the Model, and you are using ModelDriven and paramsPrepareParamsStack, what I think is going on is:

  • ModelDriven Interceptor is delegated to handle the Model object;
  • The first time you call Parameters Interceptor, ModelDriven Interceptor has not run yet;
  • Then your Action knows nothing about the Model object, and try to find the Setters for your parameters in the Action, NOT in the Model.
  • The second interceptor instead runs after the ModelDriven one, and knows exactly where to set the parameters. This is why you have the parameters correctly set in the Action method.

But if this is true, then you should NOT be able to retrieve those parameters in the prepare() method (that is the reason you are using this stack...):
please try, and post here the result.

The first thing that comes to my mind to resolve this issue, is to place the ModelDriven Interceptor before the first Parameters Interceptor (by either copying it, or by moving it, I'm not sure which kind of side effect, if any, it could produce in both cases, you should again try and reporting it here).

Then define the following stack, and use it.

<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>

Hope that helps.

这篇关于意外异常在'类xxx上设置了'xxx':错误设置表达式'xxx',其值为['x',]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆