OGNL array and list indexing

I am sending this parameter to my struts action

CDATA [1] = bar

In my action, I'm interested in index and value. I have defined a getter / setter pair for CDATA , as the OGNL documentation suggests:

 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 } 

This is the Exception I get:

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

If I define the variable public member String[] cdata = new String[1000] , I do not see any exceptions in my log, but my setter is also not called. If the member variable is private, I get another exception again.

+4
source share
3 answers

Use the following setting

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

represent values ​​from the JSP, such as cdata [1] = value, etc.

The only requirement is to have getters / setters. I tested this Tomcat7 running on java 1.6. You can imagine values ​​like cdata [0], cdata [1], as well as

otherwise you can use the card

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

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

Gets the settlement no problem

+2
source

My solution (rather ugly hacking):

I implemented the implementation of the action class ServletRequestAware and in action ServletRequestAware over the parameter map from HttpServletRequest , extracted cdata from it and analyzed it for the index and value

I had to change the sent parameter and encode, for example cdata[999]=foobar , like cdata_999_=foobar , because if it looks like struts in an array requires the / getter set for it in the action class.

+1
source

You better read the docs. Docs say

JavaBeans supports the concept of indexed properties. In particular, this means that the object has a set of methods that follow the following pattern:

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

You have not used all of these methods.

0
source

All Articles