我正在尝试设置一些看起来像是设置预订的多屏幕过程。
我已经设置了我的.jsp和xml webflow以及所有类,但我在链接它们时遇到了问题。我想在流程的开头创建一个Account类。填写第一个屏幕时,信息将存储在该类中。在最终屏幕上,用户可以根据他提供的信息查看摘要,并在必要时进行修改,当他返回第一个屏幕时,信息将已经为他填写,因此他不必重新进入。 / p>
我很抱歉代码墙。我试图将它最小化到我能想到的错误的可能位置。
我的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>
我的常规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");
}
}
所以在我的第一个屏幕的java脚本中我会有类似的东西:
<form:form modelAttribute="booking" action="${flowExecutionUrl}" method="post">
<form:input type="text" path="username"/>
</form:form>
在提示到下一个屏幕后,我想在摘要中返回值,例如
<form:form modelAttribute="booking" action="${flowExecutionUrl}" method="post">
<spring:bind path="username">${status.value}</spring:bind>
</form:form>
我得到的错误是:
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'
我尝试了另一种方法来完成所有这些,就像在我的servlet中定义一个bean一样:
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="prototype" />
但这也没有帮助,给出了同样的错误。
我对网络流量和春天都很陌生,所以如果我犯的错误很明显,请原谅我。
谢谢
答案 0 :(得分:1)
从看起来你需要在多个流之间共享对象。我想你可以在会话范围中存储对象
所以
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="prototype" />
将更改为
<beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="session" />
答案 1 :(得分:1)
使用Spring Webflow时使用会话作用域不是最好的方法。如果要在屏幕/流之间共享对象,请使用会话范围。如果需要在同一流程中的屏幕之间共享对象,请使用流量范围。
SWF范围是一种特殊形式的会话和http会话中定义的请求范围。
应用程序中需要的任何内容都应存储在http会话对象
中