Announcement Announcement Module
Collapse
No announcement yet.
Is list auto growing binding supported? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Is list auto growing binding supported?

    In his Spring MVC 3 Showcase Keith demonstrated a great feature called of auto growing lists and maps during JavaBean binding. That feature was introduced as part of Type Conversion framework.

    Since Webflow claims it uses type conversion for nearly all type conversion needs I thought I could auto growing in my flow.

    I'm working on a flow similar to shopping card. On the first state the user populates the list of items and their quantities, on the second one he is supposed to fill in serial numbers so that each item has exactly the same amount of serial numbers as its quantity.

    That's how I generate fields for serial numbers:
    Code:
    <c:forEach items="${item.serialNumbers}" varStatus="status">
      <tr>
        <td>
          <form:input path="serialNumbers[${status.index}].value" />
          <form:errors cssClass="errors" path="serialNumbers[${status.index}].value" />
        </td>
      </tr>
    </c:forEach>
    <c:forEach begin="${fn:length(item.serialNumbers)}" end="${item.quantity - 1}" varStatus="status">
      <tr>
        <td>
          <input type="text" name="items[${itemIndex}].serialNumbers[${status.index}].value" />
        </td>
      </tr>
    </c:forEach>
    I omitted the outer loop item loop for simplicity.

    Whenever I try to use auto growing for serial numbers I get
    Code:
    org.springframework.expression.spel.SpelEvaluationException: EL1025E:(pos 22): The collection has '0' elements, index '0' is invalid
    Seen from the exception message I conclude that the list in not being auto grown .

    Maybe I am missing something obvious? Is auto growing supported for Webflow?

    I will gladly provide any information needed to solve this issue.

  • #2
    In your config, you can specify which expression parser bean you want to use on flowBuilderServices.

    Create a WebFlowSprinELExpressionParser bean, which you can construct using the SpelExpressionParser. When you setup SpelExpressionParser you can set a couple of config flags, the one you want is autoGrowCollections.

    Beware of the security risk. If users can directly specify something that gets plugged in as an index, they could choose 999999 or something big which would extend your arraylist or whatever. There is an open ticket for this issue I believe.

    Comment


    • #3
      drh, you saved me a ton of nerves! Thank you a lot.

      Here's the relevant part of resulting appContext:

      HTML Code:
        <bean id="webflowConversionService" class="org.springframework.binding.convert.service.DefaultConversionService">
          <constructor-arg ref="applicationConversionService" />
        </bean>
      
        <bean id="expressionParser" class="org.springframework.expression.spel.standard.SpelExpressionParser">
          <constructor-arg name="configuration">
            <bean class="org.springframework.expression.spel.SpelParserConfiguration">
              <constructor-arg name="autoGrowCollections" value="true" />
              <constructor-arg name="autoGrowNullReferences" value="false" />
            </bean>
          </constructor-arg>
        </bean>
      
        <bean id="webflowExpressionParser" class="org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser">
          <constructor-arg name="expressionParser" ref="expressionParser" />
          <constructor-arg name="conversionService" ref="webflowConversionService"/>
        </bean>
      
        <webflow:flow-builder-services id="flowBuilderServices" expression-parser="webflowExpressionParser" view-factory-creator="mvcViewFactoryCreator" conversion-service="webflowConversionService" />
      In my case I needed integration of MVC Conversion Service with WebFlow Conversion service. If you don't need such integration you may go ahead with the default ones constructed by WebFlow:

      HTML Code:
        <bean id="expressionParser" class="org.springframework.expression.spel.standard.SpelExpressionParser">
          <constructor-arg name="configuration">
            <bean class="org.springframework.expression.spel.SpelParserConfiguration">
              <constructor-arg name="autoGrowCollections" value="true" />
              <constructor-arg name="autoGrowNullReferences" value="false" />
            </bean>
          </constructor-arg>
        </bean>
      
        <bean id="webflowExpressionParser" class="org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser">
          <constructor-arg name="expressionParser" ref="expressionParser" />
        </bean>
      
        <webflow:flow-builder-services id="flowBuilderServices" expression-parser="webflowExpressionParser" view-factory-creator="mvcViewFactoryCreator" />

      Comment

      Working...
      X