I am trying to set up something that will look like a multiple screen process of setting up a booking for example.
- Screen 1 Add personal information
- Screen 2 Contact information
- Screen 3 Summary and confirm
I have set up my .jsp and xml webflow and all of the classes, but I am having problems linking them. I want to create an Account class at the beginning of the flow. When the first screen is filled out, the information gets stored in that class. When at the final screen the user can view the summary based on the information he provided and revise if necessary, when he goes back to first screen, the information will be filled out already for him so he does not have to re-enter.
I am sorry for the wall of code. I tried to minimize it to the possible places for an error I could think of.
My flow-config.xml
<?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">
<on-start>
<evaluate expression="BookingManagementService.createBooking()" result="flowScope.booking" />
</on-start>
<view-state id="flow-config" view="booking/BookingIdentificationScreen" model="booking">
<binder>
<binding property="username" />
</binder>
<transition on="next" to="enterContactDetails"/>
<transition on="cancel" to="cancel"/>
</view-state>
...
</flow>
My general servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.mycompany.myapp" />
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<beans:bean name="/index.do" class="com.mycompany.myapp.IndexController" />
<beans:bean name="/home.do" class="com.mycompany.myapp.HomeController" />
<beans:bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<beans:property name="mappings" value="/account/flow-config.do=flowController" />
<beans:property name="alwaysUseFullPath" value="true"/>
</beans:bean>
<!-- SPRING WEB FLOW STUFF -->
<beans:bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
<beans:property name="flowExecutor" ref="flowExecutor"/>
</beans:bean>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path="/WEB-INF/config/flow-config.xml"/>
</webflow:flow-registry>
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator"/>
<beans:bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<beans:property name="viewResolvers">
<beans:list>
<beans:ref bean="viewResolver"/>
</beans:list>
</beans:property>
</beans:bean>
</beans:beans>
BookingManagementService.java
@Service("bookingService")
public class BookingManagementService{
@Transactional(readOnly = true)
public BookingIpl createBooking(Long hotelId, String username) {
BookingIpl booking= new BookingIpl();
return booking;
}
}
BookingIpl.java
@Entity
public class BookingIpl implements Serializable {
public String username;
...
}
IndexController
@Controller
public class IndexController extends AbstractController {
private BookingManagementService bookingService;
@Autowired
public IndexController(BookingManagementService bookingService) {
this.bookingService = bookingService;
}
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
return new ModelAndView("index");
}
}
so in my java scripts for the first screen I would have something like:
<form:form modelAttribute="booking" action="${flowExecutionUrl}" method="post">
<form:input type="text" path="username"/>
</form:form>
and after the prompt to the next screen I want to return the value in a summary for example
<form:form modelAttribute="booking" action="${flowExecutionUrl}" method="post">
<spring:bind path="username">${status.value}</spring:bind>
</form:form>
The error I am getting is along the line of:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/myapp] threw exception [Request processing failed; nested exception is org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [AnnotatedAction@778e65f2 targetAction = [EvaluateAction@25c73030 expression = bookingService.createBooking(), resultExpression = flowScope.booking], attributes = map[[empty]]] in state 'null' of flow 'flow-config' -- action execution attributes were 'map[[empty]]'] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'bookingService' cannot be found on object of type 'org.springframework.webflow.engine.impl.RequestControlContextImpl'
I tried another method to do all of this which is defining a bean in my servlet like so:
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="prototype" />
but this did not help either, gave the same error.
I am very new to web-flow and spring, so please forgive me if the mistake I made was something obvious.
Thank you
From what it looks that you need to share object between Multiple flows. I guess you can store object in session scope
so
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="prototype" />
Would be changed to
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="session" />
Using session scoped not best way when using Spring Webflow. If you want to share objects between the screens/flows use conversation scope. Use flow scope if you need to share the object between the screens in the same flow.
SWF scopes are in a way specialised form of session and request scopes defined in http session.
Anything needed across the application should be stored in http session object
来源:https://stackoverflow.com/questions/14630546/sharing-object-across-screens-using-spring-webflow