Announcement Announcement Module
Collapse
No announcement yet.
problem with flow transition Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • problem with flow transition

    Hi, I am new to webflow and have the following problem. It seems that my flow doesn't recognize the eventId when I pass it through the form submit. Here are my configurations:

    edit.jsp page:
    Code:
     
            <form:form modelAttribute="item">
            
                <spring:bind path="callNo">
                    <label>CallNo: <input type="text" name="${status.expression}" value="${status.value}"/></label>
                </spring:bind>
    
      <!-- other input fields -->
    
                <input type="submit" id="save" name="_eventId_save" value="Save"/>
                <input type="submit" id="cancel" name="_eventId_cancel" value="Cancel"/>
                <input type="submit" id="delete" name="_eventId_delete" value="Delete"/>
            </form:form>
    edit-flow.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow
                            http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
    
        <persistence-context/>
        <input name="id" required="true" /> 
        <on-start>
          <evaluate expression="itemService.getItem(id)" result="flowScope.item" />
          <evaluate expression="statusService.listAllStatus()" result="flowScope.statuses" />
          <evaluate expression="typeService.getAllTypes()" result="flowScope.type" />
        </on-start>
        <view-state id="editItem" view="item/edit" model="item">
            <transition on="save" to="doSave"/>
            <transition on="cancel" to="doCancel"/>
        </view-state>
        <action-state id="delete">
            <evaluate expression="itemService.removeItem(item)"/>
            <transition to="externalRedirect:contextRelative:/moderate"/>
        </action-state>
        <action-state id="doSave">
            <evaluate expression="itemService.saveItem(item)"/>
            <transition to="view"/>
        </action-state>
        <end-state id="view" commit="true" view="externalRedirect:contextRelative:/item/view?id=${item.id}"/>
        <end-state id="doCancel" commit="false" view="externalRedirect:contextRelative:/item/view?id=${item.id}"/>
    </flow>
    dispatcher-servlet.xml:
    Code:
    <?xml version="1.0" encoding="windows-1252"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
      
        <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="interceptors">
                <list>
                    <ref bean="openSessionInViewInterceptor"/>
                </list>
            </property>
            <property name="mappings">
                <map>
                    <entry key="/login/**" value-ref="loginHandler"/>
                    <entry key="/accessdenied*" value-ref="accessDeniedHandler"/>
                    <!-- other controller mappings --> 
                    <entry key="/*" value-ref="defaultHandler"/>
                </map>
            </property>
    
            <property name="defaultHandler" ref="defaultHandler" />
            <property name="alwaysUseFullPath" value="true"/>
        </bean>
    
        <bean name="flowUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="order" value="2"/>
            <property name="mappings">
                <map>
                    <entry key="/item/edit/**" value-ref="flowController"/>
                </map>
            </property>
        </bean>
    
       <!-- Bring in the WebFlow configuration    -->
       <import resource="classpath:priceanalysis-webflow.xml"/>
    
        <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver"
              p:prefix="/WEB-INF/jsp/"
              p:suffix=".jsp"
              p:order="0"/>
    
        <bean id="exceptionResolver"
            class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <prop key="java.lang.Exception">errors/error</prop>
                </props>
            </property>
            <property name="defaultErrorView" value="errors/error"/>
        </bean>
    
        <!--    controllers    -->
    
        <bean id="defaultHandler" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
          <property name="viewName" value="index" />
        </bean>
    <!-- other controllers -->
    webflow configuration:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:webflow="http://www.springframework.org/schema/webflow-config"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
    
        <bean name="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
            <property name="flowExecutor" ref="flowExecutor"/>
        </bean>
        
        <bean name="hibernateFlowExecutionListener"
            class="org.springframework.webflow.persistence.HibernateFlowExecutionListener">
            <constructor-arg ref="sessionFactory" index="0"/>
            <constructor-arg ref="txManager" index="1"/>
        </bean>
       
        <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"> 
            <webflow:flow-execution-listeners>
                <webflow:listener ref="hibernateFlowExecutionListener"/>
            </webflow:flow-execution-listeners>
        </webflow:flow-executor>
    
       <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
          <webflow:flow-location id="edit" path="/WEB-INF/jsp/item/edititem-flow.xml"/>
       </webflow:flow-registry>
    
        <bean id="flowBuilderServices" class="org.springframework.webflow.engine.builder.support.FlowBuilderServices">
            <property name="development" value="true"/>
            <property name="conversionService">
                <bean class="com.alniks.priceanalysis.mvc.webflow.PriceConversionService"/>
            </property>
            <property name="viewFactoryCreator">
                 <bean class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
                     <property name="viewResolvers">
                        <list>
                            <ref bean="viewResolver" />
                        </list>
                    </property>
                 </bean>
            </property>
            <property name="expressionParser">
                <bean class="org.springframework.webflow.expression.el.WebFlowELExpressionParser">
                    <constructor-arg >
                        <bean class="org.jboss.el.ExpressionFactoryImpl"/>
                    </constructor-arg>
                </bean>
            </property>
        </bean>
    
    </beans>
    When I press the cancel or save button, the page simply reloads. However when I add _eventID=cancel to the url: item/edit?execution=e20s1&_eventID=cancel, all work as it should be - the transition goes to cancel view. Does anybody knows what causes this problem?

  • #2
    After studying request attributes I found what may be causing my problem. Here is how webflowViewActionStateHolder looks like:
    Code:
    [ViewActionStateHolder@1be32243 eventId = 'cancel', mappingResults = Mapping Results = [[Success@5cde6b02 code = 'success', error = false, originalValue = '728', mappedValue = '728'], [Success@e437ff0 code = 'success', error = false, originalValue = '73117', mappedValue = '73117'], [Success@71846ce0 code = 'success', error = false, originalValue = '282', mappedValue = '282'], [Success@2d082059 code = 'success', error = false, originalValue = '1562-8515', mappedValue = '1562-8515'], [TargetAccessError@7083ca27 code = 'typeMismatch', error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value [] could not be coerced to type [com.alniks.priceanalysis.domain.pojo.Status], originalValue = '', mappedValue = [null]], [Success@5c4d0026 code = 'success', error = false, originalValue = '4', mappedValue = '4'], [TargetAccessError@4344ee21 code = 'typeMismatch', error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value [] could not be coerced to type [com.alniks.priceanalysis.domain.pojo.Type], originalValue = '', mappedValue = [null]], [TargetAccessError@626ddb07 code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property 'execution' not found on context of class [com.alniks.priceanalysis.domain.pojo.Item], originalValue = 'e1s1', mappedValue = [null]]]]
    After removing the problem fields from my jsp form, the flow began to work fine. However I run into another problem of property conversion. I have implemented custon conversionService:
    Code:
    public class PriceConversionService extends DefaultConversionService {
    
        @Override
        protected void addDefaultConverters() {
            super.addDefaultConverters();
            addConverter(new TypeConverter());
            addConverter(new StatusConverter());
        }
    }
    The converters:
    Code:
    public class StatusConverter extends StringToObject {
    
        public StatusConverter() {
            super(Status.class);
        }
        @Override
        protected Object toObject(String string, Class targetClass) throws Exception {
            return new Status(string);
        }
        @Override
        protected String toString(Object object) throws Exception {
            Status status = (Status) object;
            return status.toString();
        }
    }
    
    public class TypeConverter extends StringToObject {
    
        public TypeConverter (){
            super(Type.class);
        }
        @Override
        protected Object toObject(String string, Class targetClass) throws Exception {
            return new Type(string);
        }
        @Override
        protected String toString(Object object) throws Exception {
            Type type = (Type) object;
            return type.toString();
        }
    }
    The converstion service does not seem to work. In debugging mode the converting methods are never hit.

    Comment


    • #3
      Problem solved. The last step was to add
      Code:
      <binder>
                  <binding property...
      to flow config. Now it works.

      Comment

      Working...
      X