2013-04-29 136 views
4

我送這個參數來我的支柱作用OGNL數組和列表索引

CDATA [1] = BAR

在我的行動,我感興趣的指數值。 我限定的吸氣/設定器對,用於CDATA作爲OGNL documentation表明:

public void setCdata(int index, String value){ 
    LOG.info("setData; key="+ key +"; value="+ value); 
    // store index and value; 
} 

public String getCdata(int index){ 
    return null; // don't really need a setter 
} 

這是例外我得到:

2013-04-29 15:38:49,792 [http-apr-8080-exec-3] WARN com.opensymphony.xwork2.util.logging.commons.CommonsLogger.warn(CommonsLogger.java:60) - Error setting expression 'cdata[1]' with value '[Ljava. 
lang.String;@4223d2a4' 
ognl.OgnlException: target is null for setProperty(null, "1", [Ljava.lang.String;@4223d2a4) 
     at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2309) 
     at ognl.ASTProperty.setValueBody(ASTProperty.java:127) 
     at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220) 
     at ognl.SimpleNode.setValue(SimpleNode.java:301) 
     at ognl.ASTChain.setValueBody(ASTChain.java:227) 
     at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220) 
     at ognl.SimpleNode.setValue(SimpleNode.java:301) 
     at ognl.Ognl.setValue(Ognl.java:737) 
     ... 

如果我定義了一個公共成員變量String[] cdata = new String[1000]我沒有看到任何在我的日誌中的例外,但我的二傳手也沒有被調用。如果該成員變量是私人的,我再次得到另一個異常。

+0

你能指點我提到的文檔嗎? – 2013-04-30 05:54:05

+1

@LukaszLenart:我相信OP指的是這個文檔http://commons.apache.org/proper/commons-ognl/language-guide.html#Indexing。 – 2013-04-30 08:23:22

回答

2

使用以下設置

List<String> cdata = new ArrayList<String>(); 

public List<String> getCdata() { 
    return cdata; 
} 

public void setCdata(final List<String> cdata) { 
    if (cdata == null) { 
     this.cdata = new ArrayList<String>(); 
    } else { 
     this.cdata = cdata; 
    } 
} 

從JSP提交的值等CDATA [1] =值等

唯一的要求是具有getter/setter方法。我測試了這個在java 1.6上運行的Tomcat7。您可以提交類似CDATA [0],CDATA值[1]同樣

否則你可以使用地圖

private Map<String, String> data = new HashMap<String, String>(); 

public Map<String, String> getData() { 
    return data; 
} 

public void setData(Map<String, String> data) { 
    this.data = data; 
} 

JSP可以有

<s:form action="indexProperty"> 

    <h3>Test The Map</h3> 
    <input type="text" name="data['0']"/> 
    <input type="text" name="data['1']"/> 

    <s:iterator value="data.entrySet()" var="aData"> 
     <s:property value="#aData.key" />-<s:property value="#aData.value" /> 
    </s:iterator> 

    <input type="submit" name="submit" value="submit"/> 
</s:form> 

被填充沒有問題

+0

我在每個開頭都複製了所有代碼添加的日誌輸出。 getCdataValues是唯一一個被異常調用的方法 - 我剛剛添加了堆棧跟蹤到我原來的問題。 – 2013-04-30 13:09:02

+0

@kosmičák我編輯了我的答案。唯一的要求是有適當的getter/setter和使用列表 – 2013-04-30 17:25:56

+0

是的,這個工作...我在我的應用程序的其他地方使用相同的方法傳遞參數。是一個「真正的」數組而不是稀疏陣列作爲cdata在這裏。缺點是,如果索引是1000,並且這是唯一傳遞的字段,則無論如何都會爲所有1000個列表項分配空間。我希望ognl/struts使我可以自己照顧這個sparce數組,並且OGNL文檔明確指出它應該是可能的:http://commons.apache.org/proper/commons-ognl/language- guide.html#索引我不知道stuts如何使用ognl,因爲行爲是相反的。 – 2013-04-30 22:01:14

0

您應該更好地閱讀文檔。文檔說

JavaBeans支持索引屬性的概念。具體而言,這意味着一個對象有一組遵循下面的模式方法:

public PropertyType[] getPropertyName(); 
public void setPropertyName(PropertyType[] anArray); 
public PropertyType getPropertyName(int index); 
public void setPropertyName(int index, PropertyType value); 

你沒有實現所有的這些方法。

+0

是的,這是文檔說的,但我仍然不明白。第二種方法應該做什麼,如果它提供了將由ognl設置的數組,那麼第四種方法的要點是什麼? – 2013-04-30 09:47:05

+0

這意味着你應該創建'String [] getCdata()',因爲你正在使用數組。 – 2013-04-30 13:20:28

+0

它也不適用於所有四種方法。它不知道如何初始化String []。我想我將不得不初始化數組,並提前知道最高可能的索引,否則我會得到一個ArrayIndexOutOfBoundsException。索引可能是1000,但我不需要999個先前數組字段的空間。這是浪費空間。它仍然沒有解釋第四種方法 - 如果它得到數組,它可以在特定的索引本身設置值,爲什麼叫我自己的setter去做呢? – 2013-04-30 13:45:09

1

我的解決方案(而不是一個醜陋的黑客):

我讓我的行動類實現ServletRequestAware和在動作迭代在從HttpServletRequest參數映射,從中取CDATA並解析它爲索引和值

我不得不改變發送參數和編碼例如cdata[999]=foobarcdata_999_=foobar,因爲如果它看起來像一個陣列field struts要求在動作類中有一個setter/getter。