I upgraded from 2.1.6 to 2.3.15.1 because of the security fixes available in the latest version. However, now the form field values are not posted to the Action class. Basi
Solved it. With the new Struts versions parameter names are more restrictive. In my case, I had parameter names such as props['1.2.3'], props['a.b.c'] or props['a-b-c']
. These were filtered out by the new struts. Here is the link which explains this: http://struts.apache.org/development/2.x/docs/s2-009.html. The very last part explains why the collections might stop working.
I changed the acceptParamNames in the interceptor stack to <param name="acceptParamNames">\w+((\.\w+)|(\[\d+\])|(\['\w+(\-\w+)*'\]))*</param>
and it solved the issue. I got rid of the props['a.b.c']
property names so the above regex does not cover it, but it does cover props['a-b-c']
.
Thanks to @Roman C for coming forward to help me.
There have been huge changes since Struts 2.1.6. Struts 2 will not create objects for you if you don't explicitly tell it to do. The prepare
method calls before the params
interceptor sets props
to the action, and you commented that you populate the map
//fill up props map here.
not surprisingly, that Struts not call that setter setProps
because it already contains a map instance. So, it simply calls getProps
. Then it should set the indexed property values to the map. But it doesn't know a type of the object that is an element of the collection to convert to, and if it should create a new object for element if it's null
. By putting annotations on the props
field it should solve the problem populating a map on submit.
@Element(value = Wall.class)
@CreateIfNull(value = true)
private Map<String, Wall> props = new HashMap<>();
I guess the key it will determine automatically. The same could be done if you specify it in Action-conversion.properties
Element_props=Wall
CreateIfNull_props=true
Next your JSP could be replaced to
<s:iterator value="props">
<s:textfield name="props['%{key}'].value" />
</s:iterator>
And last the Wall
class you haven't posted, should look like
public class Wall {
String value;
//getter and setter here
}