I have a problem using Struts1 ActionForm beans. Please, see a part of my struts-config:
<!-- RuleSearchForm is a sublass of RuleForm -->
form-beans>
<form-bean name="ruleForm"
type="forms.RuleForm">
</form-bean>
<form-bean name="ruleSearchForm"
type="forms.RuleSearchForm">
</form-bean>
</form-beans>
<!-- Mappings -->
<action path="/RuleList"
type="actions.RuleList"
name="ruleSearchForm"
scope="session"
validate="false">
<forward name="success" path="/html/view/RuleList.jsp"></forward>
</action>
<action path="/RuleCreate"
type="actions.RuleCreate"
name="ruleForm"
scope="request"
validate="false">
<forward name="success" path="/html/view/CreateUpdateRule.jsp"></forward>
</action>
And parts of my Actionform beans code:
public class RuleForm extends ActionForm {
protected Integer crid;
protected List levels;
/** Some other fileds go here */
public Collection getLevels(){
if(levels == null){
levels = DAOClass.getLevels();
Collections.reverse(levels);
}
return levels;
}
/** Other getters/setters go here */
}
public class RuleSearchForm extends RuleForm{
/**
* Avoid filter reset. If needs to be reset use {@link RuleForm#resetBeanFields()} directly.
* */
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
/**
* Add empty value. User should have an opportunity not to set value for this field.
* */
public Collection getLevels(){
if(levels == null || levels.size() == 0){
super.getLevels();
levels.add(0, new Level());
}
return levels;
}
}
The problem is:
User goes to /RuleList.do and sees the list of rules. ruleSearchForm used as a bean for transferring search params to /RulesList.do action. Initially tihs bean is empty, only getLevels() returns "empty value" + list of levels got from superclass method.
User goes to /CreateRule.do, ruleForm is used for collecting user input. levels property is used in selectbox. And I get there list of levels + empty row. This empty row is not added in RuleForm (named ruleForm). It's added it subclass of RuleForm. Why does super class ActionForm bean with NO static fields, with other name gets values from it's sublass instance???
If users saves Rule and has been redirected to /RuleList.do, the he sees populated (i.e. filled) search form ("ruleSearchForm") with values from "ruleForm".
What does it mean? Please help, I don't understand this mess of data beetween ActionForm Beans
UPD: Now, I've changed inheritance of FormAction beans. I've introduced BaseFormBean. This BaseFormBean got two children: RuleForm and RuleSearchForm. It didn't help. Still attributes from one bean are moved to another.
My jsp code: CreateUpdateRule.jsp:
<html:form action="/RuleSave.do">
<html:hidden property="crid"/>
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td><bean:message key="rule.levelId"/></td>
<td><html:select property="levelId">
<html:optionsCollection property="levels" value="clid" label="name" />
</html:select>
</tr>
<tr>
<td><bean:message key="rule.timeStart"/></td>
<td><html:text property="timeStartStr"/></td>
</tr>
<tr>
<td><bean:message key="rule.timeEnd"/></td>
<td><html:text property="timeEndStr"/></td>
</tr>
<tr>
<td>
<html:submit styleClass="wpsButtonText"><bean:message key="application.submit"/></html:submit>
</td>
<td>
<input type="button" onclick="cancelOperation()" class="wpsButtonText" value="<bean:message key="application.cancel"/>" />
<html:link styleClass="cancelLink" page="/RuleList.do"></html:link>
</td>
</tr>
</table
</html:form>
my RuleList.jsp:
<html:form action="/CritRuleList.do" >
<table style="width: 100%;">
<tr>
<td><bean:message key="rule.levelId"/></td>
<td><html:select property=levelId">
<html:optionsCollection property="levels" value="clid" label="name" />
</html:select>
</td>
</tr>
<tr>
<td><bean:message key="rule.timeStart"/></td>
<td><html:text property="timeStartStr" /></td>
</tr>
<tr>
<td><bean:message key="rule.timeEnd"/></td>
<td><html:text property="timeEndStr" /></td>
</tr>
<tr>
<td colspan="2">
<html:submit styleClass="wpsButtonText"><bean:message key="application.search"/></html:submit>
<input type="button" onclick="cancelOperation(this)" class="wpsButtonText" value="<bean:message key="critrule.searchClear"/>" />
<html:link styleClass="cancelLink" page="/RuleResetSearchFilter.do"></html:link>
</td>
</tr>
</table>
</html:form>
It sounds very strange that a subclass method would be called in the case you've described. To find out why it's happening, you need to debug your code - put a breakpoint inside the if construct of the RuleSearchForm.getLevels()
method and see if it is really called (and where did the call originate from).
Other than that, you could try to move the populating logic of levels away from the form(s) altogether, and instead do it in the action. So, in the RuleCreate action you would do something like this:
List levels = DAOClass.getLevels();
Collections.reverse(levels);
request.setAttribute("levels", levels);