我正在用 Spring Roo 编写一个带有 MVC 和持久性脚手架的 spring webflow。在这个流程中,用户应该创建一个实体的多个实例,而这些实例又将被另一个实体引用。为简单起见,我将这些实体命名为 MyClass1 和 MyClass2。我很难弄清楚如何保留持久实体列表,这是确认时需要的。
我之前发布了一个关于同一主题的问题。但是,我确实觉得编辑原始问题(甚至更多)以进一步澄清我的问题会违反 SO-“协议”,因此我决定询问原始问题的改进版本。回想起来,我意识到原来的问题应该更准确。我可能会为此感到兴奋,但我觉得这个问题足够重要(至少对我来说!)接受它。:)
我包括了我的 roo 脚本,让任何人都可以轻松地重现我的设置。这里是:
project --topLevelPackage com.test.webflow
persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
entity --class ~.domain.Class1 --testAutomatically
field string --fieldName name
entity --class ~.domain.Class2 --testAutomatically
field string --fieldName name
field reference --fieldName class1 --type ~.domain.Class1
controller scaffold --class ~.web.Class1Controller --entity ~.domain.Class1
controller scaffold --class ~.web.Class2Controller --entity ~.domain.Class2
web flow --flowName registration
/WEB-INF/views/registration 中的 flow.xml 如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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="new java.util.ArrayList()" result="flowScope.myList" result-type="java.io.Serializable"/>
</on-start>
<view-state id="view-state-1" view="registration/view-state-1" model="class1">
<on-entry>
<evaluate expression="new com.test.webflow.domain.Class1()" result="flowScope.class1"/>
</on-entry>
<transition on="repeat" to="view-state-1"/>
<transition on="success" to="view-state-2"/>
<transition on="cancel" to="end-state"/>
<on-exit>
<evaluate expression="class1.persist()" result="flowScope.class1"/>
<evaluate expression="myList.add(class1)"/>
</on-exit>
</view-state>
<view-state id="view-state-2" view="registration/view-state-2">
<transition on="cancel" to="end-state"/>
</view-state>
<end-state id="end-state" view="registration/end-state"/>
</flow>
(在流程的真实版本中,会有另一个视图状态,其中 Class2 的实体将被注册。)view-state-1.jspx
看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<spring:message var="title" code="webflow_state1_title" htmlEscape="false" />
<util:panel id="title" title="${title}">
<h1>${fn:escapeXml(title)}</h1>
<p>
<spring:message code="webflow_state1_message" />
</p>
<form:form commandName="class1">
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}" />
<p>Enter name: <form:input path="name"/></p>
<div class="submit">
<spring:message var="cancel" code="button_cancel" htmlEscape="false" />
<spring:message var="proceed" code="button_proceed" htmlEscape="false" />
<spring:message var="repeat" code="button_repeat" htmlEscape="false" />
<input type="submit" id="cancel" name="_eventId_cancel" value="${fn:escapeXml(cancel)}" />
<input type="submit" id="success" name="_eventId_success" value="${fn:escapeXml(proceed)}" />
<input type="submit" id="repeat" name="_eventId_repeat" value="${fn:escapeXml(repeat)}" />
</div>
</form:form>
</util:panel>
</div>
view-state-2.jspx
看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:spring="http://www.springframework.org/tags" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:form="http://www.springframework.org/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<spring:message var="title" code="webflow_state2_title" htmlEscape="false" />
<util:panel id="title" title="${title}">
<h1>${fn:escapeXml(title)}</h1>
<p>
<spring:message code="webflow_state2_message" />
</p>
<p>
<c:forEach var="class1" items="${myList}">
<li><c:out value="${class1.name}"/></li>
</c:forEach>
</p>
</util:panel>
</div>
从我目前所读的所有内容来看,我认为我的解决方案应该有效。但是,我仍然没有得到预期的输出;即打印出每个name
字段。我得到了与我输入相同数量的 <li> 元素,但它们似乎都被评估为 null,正如我在上一篇文章中所解释的那样。谁能向我解释为什么这段代码不显示持久的 Class1.name-fields 的内容?(顺便说一句:它们确实出现在 CRUD 中。)
提前致谢!