簡體   English   中英

意外異常在'類xxx上設置了'xxx':錯誤設置表達式'xxx',其值為['x',]

[英]Unexpected Exception caught setting 'xxx' on 'class xxx: Error setting expression 'xxx' with value ['x', ]

我將一些參數傳遞給通過查詢字符串實現ModelDriven<Transporter>的動作類。

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

動作類如下。

@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()方法中。

如果paramsPrepareParamsStackdefaultStack替換,那么這些消息就會消失。

['DHL', ]這樣的表達式表示一個數組。 模型中的transporterIdtransporterName分別為LongString類型。

我究竟做錯了什么?

這里沒有涉及數組問題(即使看起來像這樣):這種異常意味着Struts無法為您的參數找到Setter:

來自ParametersInterceptor文檔

缺少參數的警告

如果沒有給定參數名稱的setter,則會在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) 

因此,預期行為允許開發人員在參數名稱或setter中發現缺少的setter或拼寫錯誤。

您可以通過在JSP中放置一個Action中不存在的元素來輕松地重現此錯誤。

由於您的屬性在模型中存在(使用其Setter),並且您正在使用ModelDrivenparamsPrepareParamsStack ,我認為正在進行的是:

  • ModelDriven Interceptor被委托處理Model對象;
  • 第一次調用Parameters InterceptorModelDriven Interceptor尚未運行;
  • 然后你的Action對Model對象一無所知,並嘗試在Action中找到參數的Setters,而不是在Model中。
  • 第二個攔截器改為在ModelDriven之后運行,並且確切地知道在何處設置參數。 這就是您在Action方法中正確設置參數的原因。

但是,如果這是真的,那么你應該能夠檢索的那些參數prepare()方法(這就是原因,你正在使用這個堆棧...):
請嘗試,並在此處發布結果。

我想到解決這個問題的第一件事就是將ModelDriven Interceptor放在第一個Parameters Interceptor ModelDriven 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>

希望有所幫助。

在您提供的代碼中,我找不到Transporter類的聲明。

所以我想也許是因為你的Transpoter類有超過2的參數,而不僅僅是id和name。

實際上,這個錯誤信息總是發生在我提到的情況。

要解決此問題,您可以定義一個只有2個屬性id和name的數據傳輸對象(DTO)。 使用此DTO接受來自jsp的參數,然后將屬性值傳遞給Transporter對象。

我在2019年看到了這個問題,並提供了一個解決方案,希望將來可以被其他人使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM