【问题标题】:Sharing object across screens, using Spring Webflow使用 Spring Webflow 跨屏幕共享对象
【发布时间】:2013-04-24 05:07:27
【问题描述】:

我正在尝试设置一些看起来像设置预订的多屏幕流程的东西。

  • 屏幕 1 添加个人信息
  • 屏幕 2 联系信息
  • 屏幕 3 总结和确认

我已经设置了我的 .jsp 和 xml webflow 以及所有的类,但是我在链接它们时遇到了问题。我想在流程开始时创建一个 Account 类。填写第一个屏幕后,信息将存储在该类中。在最后一个屏幕上,用户可以根据他提供的信息查看摘要并在必要时进行修改,当他返回第一个屏幕时,信息将已经为他填写好,因此他不必重新输入。

我为代码墙感到抱歉。我试图将它最小化到我能想到的错误的可能位置。

我的 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;
    ...
}

索引控制器

   @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" />

但这也没有帮助,给出了同样的错误。

我对 web-flow 和 spring 很陌生,所以如果我犯的错误很明显,请原谅我。

谢谢

【问题讨论】:

  • 错误提示 bookingService 但您的流程显示 BookingManagementService 不一致。

标签: spring-webflow


【解决方案1】:

使用 Spring Webflow 时使用会话范围不是最佳方式。如果您想在屏幕/流程之间共享对象,请使用对话范围。如果您需要在同一流程中的屏幕之间共享对象,请使用流程范围。

SWF 范围是在 http 会话中定义的会话和请求范围的一种特殊形式。

应用程序所需的任何东西都应该存储在 http 会话对象中

【讨论】:

    【解决方案2】:

    看起来您需要在多个流之间共享对象。我猜你可以在会话范围内存储对象

    所以

    <beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="prototype" />
    

    将改为

    <beans:bean id="bookingBean" class="com.mycompany.myapp.BookingIpl" scope="session" />
    

    【讨论】:

    • 这确实有帮助,谢谢。现在正在沿着 Web 流屏幕识别该对象。回复较晚,抱歉。我无权访问验证码。
    猜你喜欢
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多