Hello dear folks of stack overflow. I encountered a problem recently in my Struts application. I have a jsp which displays some bean value correctly (i paste only relevant part of the code, i simplified to the extreme):
<table>
<logic:iterate name="bean" property="list1" id="listItem">
<tr>
<td>
<html:checkbox name="listItem" property="selected">
</html:checkbox>
</td>
</logic:iterate>
</table>
My bean has a list1 property with its getter and setter
private List<RandomObject> list1;
public List getList1() {
return list1;
}
public void setList1(List list1) {
this.list1=list1;
}
and my sub-bean has a selected property:
private boolean selected;
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
Now, when enter this jsp, the values i get are correct, ie: if my mapped object in DB was at selected=true, the checkbox is checked. What i dont get is how do i save the changes i make in this form. When i submit, all the changes are lost. This is pure struts related, because in debug when i enter the StrutsAction linked to submit, the ActionForm i get has already lost all interesting values. Also i feel like it has to do with the fact that the value i want to retain isn't directly stored on the main bean, but rather is a property of a sub-bean, because on the same page there are a lot of other properties directly on the main bean that i have no trouble saving.
What did i miss ?
It's probably declaring incorrect
nameattributes in the rendered HTML. If you look at the generated source code for your page it probably looks like this:which would look for a
selectedfield in your form bean class.If you're using a collection that's a field in your form bean you want to be using the
<nested:form>,<nested:iterate>and<nested:checkboxStruts tags, not the<html:form>,and` ones. So it would then look like this:Note that I've removed the
nameattributes from the Struts tags, because they're not needed (in my experience they actually cause all kinds of problems - if you use<nested:*>tags don't use anameattribute). In the case of the<nested:iterate>the level of nesting is the form bean itself, so it knows that it needs to look for thelist1property in the form bean.That tag creates its own nesting level, so the
<nested:checkboxknows that it needs to look for theselectedproperty of the current element in the iteration.The rendered HTML will look something like this (for the first element):
which means the
selectedfield of the first element (index 0) in the collection referenced by thelist1field of your form bean.And, of course, you'll need to make sure that you're using a session-scoped form bean, rather than a request-scoped one.