John.Turner
Dec 11th, 2007, 01:42 AM
G'day All,
I have a requirement to retrieve a list of objects from the database, display them in a 'multi-record' form so that they can be edited, and then save the modified records back to the database. I have set up a web flow to retrieve the records from the database, and then present them to the user in a form. I am having problems binding the data to the form. I am also not sure how to access the data after it has been posted.
I have read a large number of threads on this forum and experimented with different syntax in the JSP file but still cannot render a JSP containing a form with the data bound.
I am using Spring v2.5 and Spring Web Flow v1.0.5.
Spring beans config:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles.TilesJs tlView" />
</bean>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlH andlerMapping">
<property name="mappings">
<props>
<prop key="flow.htm">flowController</prop>
</props>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles.TilesCo nfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/foo-tiles.xml</value>
</list>
</property>
</bean>
<bean id="flowController"
class="org.springframework.webflow.executor.mvc.FlowContr oller">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<flow:executor id="flowExecutor" registry-ref="flowRegistry" />
<flow:registry id="flowRegistry">
<flow:location path="/WEB-INF/flow/**/*-flow.xml" />
</flow:registry>
<bean id="retrieveRelationshipTypesAction"
class="foo.action.RetrieveRelationshipTypesAction">
</bean>
<bean id="saveRelationshipTypeAction"
class="foo.action.SaveRelationshipTypeAction"/>
<bean id="relationshipTypeFormAction"
class="foo.form.RelationshipTypeFormAction">
<property name="formObjectName" value="rtList"/>
<property name="formObjectScope" value="REQUEST" />
<property name="formObjectClass" value="java.util.ArrayList"/>
</bean>
Web flow definition:
<var name="relationshipTypes" class="java.util.ArrayList" scope="flow" />
<start-state idref="retrieveRelationshipTypes" />
<action-state id="retrieveRelationshipTypes">
<action bean="retrieveRelationshipTypesAction" />
<transition on="success" to="showRelationshipTypes" />
</action-state>
<view-state id="showRelationshipTypes" view="relationshipType.page" >
<render-actions>
<action bean="relationshipTypeFormAction" method="setupForm"/>
<action bean="relationshipTypeFormAction" method="populateList"/>
</render-actions>
<transition on="select" to="saveRelationshipType" >
<action bean="relationshipTypeFormAction" method="bind" />
<evaluate-action expression="requestScope.pgOfRelTypes">
<evaluation-result name="flowScope.relationshipTypes" />
</evaluate-action>
</transition>
</view-state>
<action-state id="saveRelationshipType">
<action bean="saveRelationshipTypeAction" />
<transition on="success" to="showRelationshipTypes" />
</action-state>
My action form class is:
package foo.form;
import...
public class RelationshipTypeFormAction extends FormAction {
private static Logger log = Logger.getLogger(RelationshipTypeFormAction.class) ;
public Event populateList(RequestContext context) throws Exception {
log.debug("populateList: in");
ArrayList<ItemRelationshipType> relationshipTypes = (ArrayList<ItemRelationshipType>) context.getFlowScope().get("relationshipTypes");
ArrayList<ItemRelationshipType> rtList = (ArrayList<ItemRelationshipType>) getFormObject(context);
rtList.clear();
rtList.addAll(relationshipTypes);
log.debug("populateList: out");
return success();
}
}
JSP page (I'm using tiles):
<jsp:directive.include file="/WEB-INF/page/tags.jsp" />
<h3>Relationship Types</h3>
<form:form action="flow.htm" commandName="rtList">
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
<input type="hidden" name="targetAction" value="error">
<table width="80%">
<tr>
<td>
ID
</td>
<td>
Name
</td>
<td>
Description
</td>
</tr>
<c:forEach items="${rtList}" var="rt" varStatus="loop">
<tr>
<td>
<%-- <c:out value="${rt.itemRelationshipTypeId}" /> --%>
<form:input path="${rtList}[${loop.index}].itemRelationshipTypeId" />
</td>
<td>
<%-- <c:out value="${rt.name}" /> --%>
<form:input path="${rtList}[${loop.index}].name" />
</td>
<td>
<%-- <c:out value="${rt.description}" /> --%>
<form:input path="${rtList}[${loop.index}].description" />
</td>
</tr>
</c:forEach>
</table>
<p>
<input type="submit" name="_eventId_cancel" value="Cancel"/>
<input type="submit" name="_eventId_save" value="Save"/>
</p>
</form:form>
When this JSP is called I get this error:
17:14:11,225 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR org.springframework.web.servlet.tags.form.InputTag - Invalid property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' of bean class [java.util.ArrayList]: Bean property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.springframework.beans.NotReadablePropertyExcep tion: Invalid property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' of bean class [java.util.ArrayList]: Bean property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPrope rtyValue(BeanWrapperImpl.java:544)
at org.springframework.beans.BeanWrapperImpl.getNeste dBeanWrapper(BeanWrapperImpl.java:451)
at org.springframework.beans.BeanWrapperImpl.getBeanW rapperForPropertyPath(BeanWrapperImpl.java:428)
...
Can anyone tell me what the correct syntax is for binding to a list? I've tried several variations on what I've presented here but with no success.
Thanks, John
I have a requirement to retrieve a list of objects from the database, display them in a 'multi-record' form so that they can be edited, and then save the modified records back to the database. I have set up a web flow to retrieve the records from the database, and then present them to the user in a form. I am having problems binding the data to the form. I am also not sure how to access the data after it has been posted.
I have read a large number of threads on this forum and experimented with different syntax in the JSP file but still cannot render a JSP containing a form with the data bound.
I am using Spring v2.5 and Spring Web Flow v1.0.5.
Spring beans config:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles.TilesJs tlView" />
</bean>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlH andlerMapping">
<property name="mappings">
<props>
<prop key="flow.htm">flowController</prop>
</props>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles.TilesCo nfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/foo-tiles.xml</value>
</list>
</property>
</bean>
<bean id="flowController"
class="org.springframework.webflow.executor.mvc.FlowContr oller">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<flow:executor id="flowExecutor" registry-ref="flowRegistry" />
<flow:registry id="flowRegistry">
<flow:location path="/WEB-INF/flow/**/*-flow.xml" />
</flow:registry>
<bean id="retrieveRelationshipTypesAction"
class="foo.action.RetrieveRelationshipTypesAction">
</bean>
<bean id="saveRelationshipTypeAction"
class="foo.action.SaveRelationshipTypeAction"/>
<bean id="relationshipTypeFormAction"
class="foo.form.RelationshipTypeFormAction">
<property name="formObjectName" value="rtList"/>
<property name="formObjectScope" value="REQUEST" />
<property name="formObjectClass" value="java.util.ArrayList"/>
</bean>
Web flow definition:
<var name="relationshipTypes" class="java.util.ArrayList" scope="flow" />
<start-state idref="retrieveRelationshipTypes" />
<action-state id="retrieveRelationshipTypes">
<action bean="retrieveRelationshipTypesAction" />
<transition on="success" to="showRelationshipTypes" />
</action-state>
<view-state id="showRelationshipTypes" view="relationshipType.page" >
<render-actions>
<action bean="relationshipTypeFormAction" method="setupForm"/>
<action bean="relationshipTypeFormAction" method="populateList"/>
</render-actions>
<transition on="select" to="saveRelationshipType" >
<action bean="relationshipTypeFormAction" method="bind" />
<evaluate-action expression="requestScope.pgOfRelTypes">
<evaluation-result name="flowScope.relationshipTypes" />
</evaluate-action>
</transition>
</view-state>
<action-state id="saveRelationshipType">
<action bean="saveRelationshipTypeAction" />
<transition on="success" to="showRelationshipTypes" />
</action-state>
My action form class is:
package foo.form;
import...
public class RelationshipTypeFormAction extends FormAction {
private static Logger log = Logger.getLogger(RelationshipTypeFormAction.class) ;
public Event populateList(RequestContext context) throws Exception {
log.debug("populateList: in");
ArrayList<ItemRelationshipType> relationshipTypes = (ArrayList<ItemRelationshipType>) context.getFlowScope().get("relationshipTypes");
ArrayList<ItemRelationshipType> rtList = (ArrayList<ItemRelationshipType>) getFormObject(context);
rtList.clear();
rtList.addAll(relationshipTypes);
log.debug("populateList: out");
return success();
}
}
JSP page (I'm using tiles):
<jsp:directive.include file="/WEB-INF/page/tags.jsp" />
<h3>Relationship Types</h3>
<form:form action="flow.htm" commandName="rtList">
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
<input type="hidden" name="targetAction" value="error">
<table width="80%">
<tr>
<td>
ID
</td>
<td>
Name
</td>
<td>
Description
</td>
</tr>
<c:forEach items="${rtList}" var="rt" varStatus="loop">
<tr>
<td>
<%-- <c:out value="${rt.itemRelationshipTypeId}" /> --%>
<form:input path="${rtList}[${loop.index}].itemRelationshipTypeId" />
</td>
<td>
<%-- <c:out value="${rt.name}" /> --%>
<form:input path="${rtList}[${loop.index}].name" />
</td>
<td>
<%-- <c:out value="${rt.description}" /> --%>
<form:input path="${rtList}[${loop.index}].description" />
</td>
</tr>
</c:forEach>
</table>
<p>
<input type="submit" name="_eventId_cancel" value="Cancel"/>
<input type="submit" name="_eventId_save" value="Save"/>
</p>
</form:form>
When this JSP is called I get this error:
17:14:11,225 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR org.springframework.web.servlet.tags.form.InputTag - Invalid property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' of bean class [java.util.ArrayList]: Bean property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.springframework.beans.NotReadablePropertyExcep tion: Invalid property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' of bean class [java.util.ArrayList]: Bean property '[foo.model.ItemRelationshipType@79b022, foo.model.ItemRelationshipType@79b00e, foo.model.ItemRelationshipType@79affa][0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPrope rtyValue(BeanWrapperImpl.java:544)
at org.springframework.beans.BeanWrapperImpl.getNeste dBeanWrapper(BeanWrapperImpl.java:451)
at org.springframework.beans.BeanWrapperImpl.getBeanW rapperForPropertyPath(BeanWrapperImpl.java:428)
...
Can anyone tell me what the correct syntax is for binding to a list? I've tried several variations on what I've presented here but with no success.
Thanks, John