Spring webflow:如何跟踪持久化实体ID?
我正在开发一个网络流(SWF2)。这些实体是使用 Roo 生成的。 Webflow 视图之一 multi-instance.jspx 可以被多次调用,以允许同一实体 (MyClass) 的多个持久实例。
我想保留这些持久实体的列表,以便我可以在流程的稍后阶段引用它们。到目前为止,我已经尝试过以下操作。
我的 flow.xml
的简化版本如下所示:
<on-start>
<evaluate expression="new java.util.ArrayList()" result="flowScope.myList" result-type="java.io.Serializable"/>
</on-start>
<view-state id="multi-instance" view="multi-instance" model="myClass">
<binder>
<binding property="field1"/>
<binding property="field2"/>
</binder>
<on-entry>
<evaluate expression="new com.test.MyClass()" result="flowScope.myClass" />
</on-entry>
<transition on="another_instance" to="multi-instance"/>
<transition on="success" to="confirm"/>
<transition on="cancel" to="abort"/>
<on-exit>
<evaluate expression="myClass.persist()"/>
<evaluate expression="flowScope.myList.add(myClass)"/>
</on-exit>
</view-state>
confirm
和 abort
视图状态在 flow.xml< 中定义/代码>也是如此。
confirm.jspx
看起来像这样:
<div xmlns:spring="http://www.springframework.org/tags" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:form="http://www.springframework.org/tags/form" 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" />
<form:form>
<c:forEach items="${myList}" var="instance">
<li>${instance.getField1()} ${instance.getField2()}</li>
</c:forEach>
<div class="submit">
<input type="submit" id="success" name="_eventId_success" value="success"/>
<input type="submit" id="cancel" name="_eventId_cancel" value="cancel" />
</div>
</form:form>
</div>
那么问题来了:
每当我点击 confirm.jspx
时,Web 返回都会显示 org.springframework.webflow 抛出异常。 engine.impl.FlowExecutionImpl.wrap(FlowExecutionImpl.java:569)。
编辑:Apache 日志更有启发性。以下是调用堆栈顶部的片段:
SEVERE: Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException:
/WEB-INF/views/myflow/confirmation.jspx(6,7)
The function getField1 must be used with a prefix when a default namespace is not specified
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
我不确定 ArrayList 方法是否可行;我相信我在某处读到,在多实例状态中定义的 flowScope.myClass 实例被 GC 拾取,或者至少超出了范围。我不知道。如果有人能够阐明这个特定主题,我会很高兴。
(如果您碰巧知道更好的方法来保存这些持久实体的列表,请随时告诉我!)提前致谢! :)
更新: 我可以像这样计算列表中的元素数量:
<c:choose>
<c:when test="${myList != null}">myList exists, it contains <c:out value="${fn:length(myList)}" /> items!</c:when>
<c:otherwise>myList doesn't exist.</c:otherwise>
</c:choose>
它显示的元素数量与我插入的元素数量相同。但是,当我这样做时:
<c:forEach items="${myList}" var="instance">
<c:if test="${instance != null}">
<li>${instance.field1} ${instance.field2}</li>
</c:if>
</c:forEach>
什么也没有显示。 (当省略空测试时,我可以确认有正确数量的
I'm working on a webflow (SWF2). The entities are generated using Roo. One of the webflow views, multi-instance.jspx, may be called multiple times to allow for multiple, persisted instances of the same entity (MyClass).
I'd like to keep a list of those persisted entities so that I can reference them on a later point in the flow. So far, I've tried the following.
A simplified version of my flow.xml
looks like this:
<on-start>
<evaluate expression="new java.util.ArrayList()" result="flowScope.myList" result-type="java.io.Serializable"/>
</on-start>
<view-state id="multi-instance" view="multi-instance" model="myClass">
<binder>
<binding property="field1"/>
<binding property="field2"/>
</binder>
<on-entry>
<evaluate expression="new com.test.MyClass()" result="flowScope.myClass" />
</on-entry>
<transition on="another_instance" to="multi-instance"/>
<transition on="success" to="confirm"/>
<transition on="cancel" to="abort"/>
<on-exit>
<evaluate expression="myClass.persist()"/>
<evaluate expression="flowScope.myList.add(myClass)"/>
</on-exit>
</view-state>
The confirm
and abort
view-states are defined in flow.xml
as well. The confirm.jspx
looks like this:
<div xmlns:spring="http://www.springframework.org/tags" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:form="http://www.springframework.org/tags/form" 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" />
<form:form>
<c:forEach items="${myList}" var="instance">
<li>${instance.getField1()} ${instance.getField2()}</li>
</c:forEach>
<div class="submit">
<input type="submit" id="success" name="_eventId_success" value="success"/>
<input type="submit" id="cancel" name="_eventId_cancel" value="cancel" />
</div>
</form:form>
</div>
So to the question:
Whenever I hit confirm.jspx
, the web return says that there's an exception thrown at org.springframework.webflow.engine.impl.FlowExecutionImpl.wrap(FlowExecutionImpl.java:569).
EDIT: The Apache log is a little more enlightening. The following is a snippet of the top of the call stack:
SEVERE: Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException:
/WEB-INF/views/myflow/confirmation.jspx(6,7)
The function getField1 must be used with a prefix when a default namespace is not specified
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
I'm not sure if the ArrayList-approach is possible; I believe I've read somewhere that the flowScope.myClass instance, as it is defined in the multi-instance
-state, is picked up by the GC or at least falls out of scope. I'm not sure. If anyone can shed some light on that particular topic, I'd be thrilled.
(And if you happen to know a better way to keep a list of these persisted entities, please feel free to let me know!) Thanks in advance! :)
Update:
I'm able to count the number of elements in my list like so:
<c:choose>
<c:when test="${myList != null}">myList exists, it contains <c:out value="${fn:length(myList)}" /> items!</c:when>
<c:otherwise>myList doesn't exist.</c:otherwise>
</c:choose>
It shows the same number of elements as I've inserted. However, when I do this:
<c:forEach items="${myList}" var="instance">
<c:if test="${instance != null}">
<li>${instance.field1} ${instance.field2}</li>
</c:if>
</c:forEach>
nothing is displayed. (I can confirm that there is a correct number of <li>-elements when the null-test is omitted. Note also that I'm trying to access the properties directly, as indicated here: jstl/jsp - iterating over a vector of beans) I don't know what to think, regarding the scope here, but it seems clear that I can't access my entities via an ArrayList.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,关于您关于变量范围的问题,我建议查看 4.4,其中描述了所有不同的可用范围。
流范围变量在流的整个生命周期中都存在。因此,在流程退出之前,您的 myClass 变量不会消失。但请记住,每次进入视图状态时,
表达式都会分配一个新实例。其次,我认为您的解决方案可能走在正确的轨道上。我要注意几件事:
元素中的列表 - 这意味着当您离开该状态时(包括当您离开该状态时),这两件事总是会发生进行取消
转换。这可能不是您想要的。相关:
实际上正在退出视图状态并重新进入它,触发
和
逻辑。只需执行
即可保持相同状态。这样做将执行转换中的任何逻辑,然后重新渲染视图而不实际更改状态。标记来初始化变量...您正在使用
可能会更干净。另外,没有必要说
result-type="java.io.Serialized"
。当您需要将返回类型转换为其他类型时,应使用result-type
。最后,您收到的错误看起来与 webflow 无关。 JSTL/EL 允许您访问 bean 属性,但不允许访问方法,并且您正在尝试调用方法。有关详细信息,请参阅此问题。
First, with regards to your question(s) around variable scoping, I would suggest looking at section 4.4 of the SWF documentation, where it describes all of the different available scopes.
Flow scope variables live through the lifetime of the flow. So your myClass variable will not go away until the flow exits. However keep in mind that your
<on-entry>
expression is assigning a new instance every time that view state is entered.Second, I think you are probably on the right track with your solution. I would note several things:
<on-exit>
element -- this means these two things will always happen when you leave the state, including when you are doing yourcancel
transition. This may not be what you want. Related:<transition on="another_instance" to="multi-instance"/>
is actually exiting the view-state and re-entering it, triggering the<on-exit>
and<on-entry>
logic. It is possible to remain in the same state, by simply doing<transition on="another_instance">
. Doing this will execute any logic you have inside the transition, and then re-render the view without actually changing states.<var>
tag to initialize variables... what you are doing with<evaluate expression="new ..."/>
works but using<var>
may be cleaner. Also, it is not necessary to sayresult-type="java.io.Serializable"
.result-type
should be used when you need to convert the return type to something elese.Finally, the error you are getting looks like it is unrelated to webflow. JSTL/EL allow you to access bean properties but not methods, and you are trying to invoke a method. See this question for more info.