You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Timmos <ti...@gmail.com> on 2009/03/28 10:26:28 UTC
Struts 2 - Dynamic form: submitting issues
Hi,
I figured out how to generate a form with dynamic length. The submitting
part remains a bit tricky, but before you redirect me to OGNL / Type
Conversion pages, I have to say I already read those articles.
This is a part of my generated .jsp (the generate part - I won't include the
Action code for this):
<s:iterator value="properties" status="stat">
<s:textfield name="lijst[2]" label="%{name}" />
</s:iterator>
As you can see, for testing purposes I hard-coded the index "2", but I don't
know if this syntax is correct.
This form is to be submitted to DoSearchAction:
public void setLijst(int index, String s) {
lijst[index] = s;
System.out.println(">>>> LIJST!!! >> " + index + ":::" + s);
}
When I run this piece of junk, I get: ognl.OgnlException: target is null for
setProperty(null, "2", [Ljava.lang.String;@13dd8).
I would like to know what is wrong with the setter / s:textfield name
parameter. What do I have to do to get it working?
--
View this message in context: http://www.nabble.com/Struts-2---Dynamic-form%3A-submitting-issues-tp22755036p22755036.html
Sent from the Struts - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Struts 2 - Dynamic form: submitting issues
Posted by Greg Lindholm <gl...@yahoo.com>.
Timmos wrote:
>
> Hi,
>
> I figured out how to generate a form with dynamic length. The submitting
> part remains a bit tricky, but before you redirect me to OGNL / Type
> Conversion pages, I have to say I already read those articles.
>
> This is a part of my generated .jsp (the generate part - I won't include
> the Action code for this):
>
> <s:iterator value="properties" status="stat">
> <s:textfield name="lijst[2]" label="%{name}" />
> </s:iterator>
>
> As you can see, for testing purposes I hard-coded the index "2", but I
> don't know if this syntax is correct.
>
> This form is to be submitted to DoSearchAction:
>
> public void setLijst(int index, String s) {
> lijst[index] = s;
> System.out.println(">>>> LIJST!!! >> " + index + ":::" + s);
> }
>
> When I run this piece of junk, I get: ognl.OgnlException: target is null
> for setProperty(null, "2", [Ljava.lang.String;@13dd8).
>
> I would like to know what is wrong with the setter / s:textfield name
> parameter. What do I have to do to get it working?
>
>
>
This will work. You just have to provide getter and setter for your list.
<s:iterator value="myList" status="stat">
<s:textfield name="myList[%{#stat.index}].field1" />
<s:textfield name="myList[%{#stat.index}].field2" />
</s:iterator>
public List<MyClass> getMyList()
{
return myList;
}
public void setMyList(List<MyClass>myList)
{
this.myList = myList;
}
--
View this message in context: http://www.nabble.com/Struts-2---Dynamic-form%3A-submitting-issues-tp22755036p22782850.html
Sent from the Struts - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Struts 2 - Dynamic form: submitting issues
Posted by Jeroen De Ridder <vo...@gmail.com>.
According to the OGNL spec, setting indexed JavaBean properties using
lijst[0], lijst[1] etc should work. And it does; except not through
struts 2's params interceptor. Try it out:
public class ActionTest extends ActionSupport {
private List<String> someProperty = new ArrayList<String>();
public ActionTest(){
try {
Ognl.setValue("someProperty[0]", this, "Foo");
}
catch(Exception ex){
ex.printStackTrace();
}
}
public String execute(){
return SUCCESS;
}
public String getSomeProperty(int index){
return someProperty.get(index);
}
public void setSomeProperty(int index, String name){
someProperty.set(index, name);
}
}
Set a breakpoint on setSomeProperty and you will find that it calls the
indexed setter exactly as it should. I've been debugging this around a
bit to see why this doesn't work through the Struts 2 params
interceptor, and I found that apparently this is due to the fact that
Struts does not pass the action instance itself as the object to
evaluate the OGNL expression against, but rather a CompoundRoot of the
action and a DefaultTextProvider.
When the OGNL expression "someProperty[0]" is evaluated, OGNL will parse
the expression into an ASTChain of 2 ASTProperty's.
ASTChain.setValueBody is then called to execute the appropriate setter.
What's preventing the indexed setter from being executed is
propertyNode.getIndexedPropertyType(context, target) returning the wrong
index type.
The index type of a property (see ASTProperty.getIndexedPropertyType)
appears to be ultimately determined in
OgnlRuntime.getIndexedPropertyType, which fetches a PropertyDescriptor
for the specified object's class and property (ie. "someProperty" in
this case). The problem here is that, since the object is a
CompoundRoot, a property descriptor for CompoundRoot.class is returned,
which understandably has no property descriptor for "someProperty" since
it has no indexed setter for "someProperty", causing it to return
INDEXED_PROPERTY_NONE (ie. not indexed) instead of
INDEXED_PROPERTY_OBJECT. When the action instance itself is passed as
the object to evaluate against, a property descriptor is fetched for the
actual action class (ActionTest.class), and an
ObjectIndexedPropertyDescriptor is returned for "someProperty" as expected.
So it looks like the root cause is that only the methods of CompoundRoot
are considered for determining any indexed setters, not those of the
objects it contains. I'm sure there are a whole slew of a problems
abound if you would propagate the lookup into the contained objects, and
even if you did, the property descriptors are only assigned once and
then reused, so you'd still only get the descriptors for the first
CompoundRoot object you encounter.
I'm fairly new to the Struts 2 and OGNL codebase and I'm not sure what
the best way to fix it would be, but I hope this might provide some
insight or even serve as a rough bug report.
>
> newton.dave wrote:
>
>> Timmos wrote:
>>
>>> Hi,
>>>
>>> I figured out how to generate a form with dynamic length. The submitting
>>> part remains a bit tricky, but before you redirect me to OGNL / Type
>>> Conversion pages, I have to say I already read those articles.
>>>
>>> This is a part of my generated .jsp (the generate part - I won't include
>>> the
>>> Action code for this):
>>>
>>> <s:iterator value="properties" status="stat">
>>> <s:textfield name="lijst[2]" label="%{name}" />
>>> </s:iterator>
>>>
>>> As you can see, for testing purposes I hard-coded the index "2", but I
>>> don't
>>> know if this syntax is correct.
>>>
>>> This form is to be submitted to DoSearchAction:
>>>
>>> public void setLijst(int index, String s) {
>>> lijst[index] = s;
>>> System.out.println(">>>> LIJST!!! >> " + index + ":::" + s);
>>> }
>>>
>>> When I run this piece of junk, I get: ognl.OgnlException: target is null
>>> for
>>> setProperty(null, "2", [Ljava.lang.String;@13dd8).
>>>
>>> I would like to know what is wrong with the setter / s:textfield name
>>> parameter. What do I have to do to get it working?
>>>
>> (1) If there are multiple parameters w/ the same name the framework
>> appears to put them into a collection: it may not be necessary to do
>> *anything*.
>>
>> (2) IIRC using indexed setters would use the (n) syntax (not [n]), but I
>> could be remembering wrong. In any case, you don't need to use an
>> indexed setter, just have an appropriate collection property with a
>> setter, say:
>>
>> private List<String> lijst;
>> public void setLijst(List l) { lijst = l; }
>>
>> (Or whatever.)
>>
>> Dave
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
>>
>>
>>
> Thx. What should the name attributes of my textfield be then, knowing that
> "lijst" is my List to set?
>
> <s:textfield value="" name"lijst" /> ? And it should work?
>
Re: Struts 2 - Dynamic form: submitting issues
Posted by Timmos <ti...@gmail.com>.
newton.dave wrote:
>
> Timmos wrote:
>> Hi,
>>
>> I figured out how to generate a form with dynamic length. The submitting
>> part remains a bit tricky, but before you redirect me to OGNL / Type
>> Conversion pages, I have to say I already read those articles.
>>
>> This is a part of my generated .jsp (the generate part - I won't include
>> the
>> Action code for this):
>>
>> <s:iterator value="properties" status="stat">
>> <s:textfield name="lijst[2]" label="%{name}" />
>> </s:iterator>
>>
>> As you can see, for testing purposes I hard-coded the index "2", but I
>> don't
>> know if this syntax is correct.
>>
>> This form is to be submitted to DoSearchAction:
>>
>> public void setLijst(int index, String s) {
>> lijst[index] = s;
>> System.out.println(">>>> LIJST!!! >> " + index + ":::" + s);
>> }
>>
>> When I run this piece of junk, I get: ognl.OgnlException: target is null
>> for
>> setProperty(null, "2", [Ljava.lang.String;@13dd8).
>>
>> I would like to know what is wrong with the setter / s:textfield name
>> parameter. What do I have to do to get it working?
>
> (1) If there are multiple parameters w/ the same name the framework
> appears to put them into a collection: it may not be necessary to do
> *anything*.
>
> (2) IIRC using indexed setters would use the (n) syntax (not [n]), but I
> could be remembering wrong. In any case, you don't need to use an
> indexed setter, just have an appropriate collection property with a
> setter, say:
>
> private List<String> lijst;
> public void setLijst(List l) { lijst = l; }
>
> (Or whatever.)
>
> Dave
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>
>
Thx. What should the name attributes of my textfield be then, knowing that
"lijst" is my List to set?
<s:textfield value="" name"lijst" /> ? And it should work?
--
View this message in context: http://www.nabble.com/Struts-2---Dynamic-form%3A-submitting-issues-tp22755036p22779033.html
Sent from the Struts - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Struts 2 - Dynamic form: submitting issues
Posted by Dave Newton <ne...@yahoo.com>.
Timmos wrote:
> Hi,
>
> I figured out how to generate a form with dynamic length. The submitting
> part remains a bit tricky, but before you redirect me to OGNL / Type
> Conversion pages, I have to say I already read those articles.
>
> This is a part of my generated .jsp (the generate part - I won't include the
> Action code for this):
>
> <s:iterator value="properties" status="stat">
> <s:textfield name="lijst[2]" label="%{name}" />
> </s:iterator>
>
> As you can see, for testing purposes I hard-coded the index "2", but I don't
> know if this syntax is correct.
>
> This form is to be submitted to DoSearchAction:
>
> public void setLijst(int index, String s) {
> lijst[index] = s;
> System.out.println(">>>> LIJST!!! >> " + index + ":::" + s);
> }
>
> When I run this piece of junk, I get: ognl.OgnlException: target is null for
> setProperty(null, "2", [Ljava.lang.String;@13dd8).
>
> I would like to know what is wrong with the setter / s:textfield name
> parameter. What do I have to do to get it working?
(1) If there are multiple parameters w/ the same name the framework
appears to put them into a collection: it may not be necessary to do
*anything*.
(2) IIRC using indexed setters would use the (n) syntax (not [n]), but I
could be remembering wrong. In any case, you don't need to use an
indexed setter, just have an appropriate collection property with a
setter, say:
private List<String> lijst;
public void setLijst(List l) { lijst = l; }
(Or whatever.)
Dave
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org