This is a part of my web-flow:
<?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"
parent="estatGeneral" start-state="a_cargar_info">
<attribute name="caption" value="consultaDeutesHandler.filAriadna" />
<action-state id="a_cargar_info">
<evaluate expression="consultaDeutesHandler.primeraCarrega(flowRequestContext, usuari)"></evaluate>
<transition on="success" to="v_formulariDeutesInici"/>
<transition on="error" to="error"/>
</action-state>
I would like to insert text from a properties bundle or backing bean into an attribute. I tried this:
<attribute name="caption" value="consultaDeutesHandler.filAriadna" />
where consultaDeutesHandler.filAriadna is a function that returns a String. Instead of the expected value I just see "consultaDeutesHandler.filAriadna" literally.
Is there a way to set the value of an attribute from a properties bundle?
The <attribute> tag will not work since it only supports plain strings, not EL expressions.
<set> should do the trick:
<set name="flowScope.caption" value="consultaDeutesHandler.filAriadna()" />
(Substitute requestScope, conversationScope, etc. for flowScope as appropriate.)
You can refer to this value later in the flow xml, and from your views. For a JSF example,
<div>#{caption}</div>
will ultimately contain the value returned from consultaDeutesHandler.filAriadna()
Related
I have a very basic flow which looks like this :
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<view-state id="gestionParametres" view="gestionParametres.xhtml">
<on-entry>
<evaluate expression="gestionParametresAction.initialiser()" />
</on-entry>
<transition on="annulerParametres">
<evaluate expression="gestionParametresAction.annulerParametres()"/>
</transition>
<transition on="enregistrerParametres">
<evaluate expression="gestionParametresAction.enregistrerParametres()"/>
</transition>
<!-- More transitions -->
</view-state>
<end-state id="back"/>
</flow>
Now when I render my page from two different navigators, a change in one page will provoke the same change in the other page. So I want to implement a mechanism that allow my flow to handle concurrent access. How can I achieve that ? I read the spring web flow documentation but I saw nothing about it. May be I am not looking in the right direction...
Thank you.
I solved it using the annotation #Scope("session") on my bean. Obviously the default scope with Spring is #Scope("singleton"), so if I understand correctly, the same instance of the bean was used for every flow using the bean. Here is an other thread that helped me.
I have two projects in my workspace: projectA, projectB. The web-flow of projectA has got the following:
<view-state id="hello" view="projectA/firstJSP" >
</view-state>
<action-state id="checkingvalues">
<evaluate expression="somethingIsthere" />
<transition on="success" to="hello" />
<transition on="error" to="bye" />
</action-state>
Its all working fine. The thing is:
if I add the following to the projectA'flow.xml then, it is not working
<view-state id="bye" view="projectB/someJSP" >
</view-state>
Here, someJSP.jsp is in projectB(path is:/projectB/WebContent/WEB-INF/common/files/someJSP.jsp)
and firstJSP.jsp is in projectA(path is:/projectA/WebContent/WEB-INF/common/gifts/firstJSP.jsp)
So is it possible to call projectB's jsp in projectA's web.xml?
No it is not allowed. At the end everything (classes, jps, htmls ..) is packed into a war file that is separated from other wars.
This should be possible.
See some examples here:
http://www.jonathanhui.com/spring-web-flow-web-flow-definiation
In your case you probably want to use something like the following:
<view-state id="bye"
view="externalRedirect:serverRelative:projectB/someJSP">
Although as I guess you would want to end the flow at this point then the following might be better:
<action-state id="checkingvalues">
<evaluate expression="somethingIsthere" />
<transition on="success" to="hello" />
<transition on="error" to="bye" />
</action-state>
<end-state id="bye" view="externalRedirect:serverRelative:projectB/someJSP"/>
I'm trying to use some #Service annotated classes (yes, using the mvc:annotation-driven) within the following Web flow :
manage-flow.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" start-state="start" >
<view-state id="start" view="Userview.jsp" >
<on-render>
<set name="flowScope.users"
value="UserService.getUsers()">
</set>
</on-render>
</view-state>
<bean-import resource="Manage-Beans.xml"/>
</flow>
Manage-Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="com.dproductions.test.Service.SiteService" id="SiteService" />
<bean class="com.dproductions.test.Service.CustomerService" id="CustomerService" />
<bean class="com.dproductions.test.Service.UserService" id="UserService" />
</beans>
When attempting to reach the flow I get the following stacktrace : http: //pastebin.com/QmCXe45Y
Which comes down to the Webflow not being able to access the specified package(s).
But it doesn't give a 'ClassNotFoundException' , which is sort of puzzling to me.
Any suggestion is welcome.
Besides, my servlet-context is found here : Servlet-context
I've been fighting this for over a week now.
Edit
I want to be able to use my beans the way they are used at This Example , at the action states, the beans being picked up/managed directly by Spring MVC .
Do the beans have to be declared (and serializable?) in the applicationcontext ? Using xml-notation ?
If I change the
<set>
towards an
<evaluate expression>
and have the beans defined in the file Manage-Beans.xml , it works.
But that way I have to define the same bean twice, as it is once picked up by the pkg-search annotation, and then in the web-flow it is again.
I'd like to have the beans which are already made.
Spring web flow DOES re-create/instantiate the bean again. You can reference properties, autowire them with beans in the web-flow beans import file, but it's like a new context, unaware of existing beans.
(Using events goes to both flow and normal-context files.)
java.lang.IllegalStateException: Exception occurred rendering view
org.springframework.web.servlet.view.JstlView: unnamed; URL
[/WEB-INF/flows/manage/Userview.jsp]
org.springframework.webflow.mvc.view.AbstractMvcView.render(AbstractMvcView.java:191)
org.springframework.webflow.engine.ViewState.render(ViewState.java:296)
org.springframework.webflow.engine.ViewState.refresh(ViewState.java:243)
org.springframework.webflow.engine.ViewState.resume(ViewState.java:221)
org.springframework.webflow.engine.Flow.resume(Flow.java:545)
org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:258)
org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:322)
Check the view file location.
I'm setting up an application using Spring Webflow 2, and I'm running into a problem. The app takes in a reservation on one page and then allows for payment on another page. The reservation model object works fine; I can fill out the form, submit it, and it shows the fully populated object on the following confirmation screen. When I do the same thing with the paymentInformation model object however, none of the form's contents are bound into the model object when it is processed.
Here's my flow definition. (I moved the payment flow into a subflow while I was trying to troubleshoot this problem.)
<?xml version="1.0" encoding="UTF-8"?>
<flow
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/webflow"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="paymentInfo" class="com.myapp.payments.domain.PaymentInfo" />
<input name="reservation" />
<decision-state id="paymentDecision">
<if test="reservationServiceImpl.needsPayment(reservation)"
then="enterPayment"
else="resolvePayment" />
</decision-state>
<view-state id="enterPayment" view="enterPayment" model="paymentInfo">
<on-render>
<evaluate expression="reservationMultiAction.preparePayment" />
<set name="viewScope.stepNumber" value="3" />
</on-render>
<transition on="back" to="editReservation" />
<transition on="submitPayment" to="resolvePayment" />
</view-state>
<action-state id="resolvePayment">
<evaluate expression="reservationMultiAction.submitPayment" />
<transition on="success" to="receipt" />
<transition on="failure" to="payment" />
</action-state>
<end-state id="editReservation" />
<end-state id="receipt" />
</flow>
Calling preparePayment populates the bean in the flowScope, and then correctly populates the form on the enterPayment page. But when I debug the submitPayment action method, the paymentInfo bean only has the results of preparePayment, and nothing from the submitted form.
And since I'm sure someone will ask, here's the opening form tag from the enterPayment page:
<form:form modelAttribute="paymentInfo" method="post">
It is hard to identify the error if full form html code is not included. At first sight, it could be a missing action attribute in the form tag.
<form:form action="${flowExecutionUrl}" modelAttribute="paymentInfo" method="post">
<input type="submit" id="_eventId" value="submitPayment" />
</form:form>
I'm having a problem with the following scxml code:
<?xml version="1.0" encoding="utf-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initialstate="global">
...
<state id="global" initial="init">
...
<state id="state2">
<onentry>
<if cond="mydata.skip">
<if cond="_event.name=='ev.prev'">
<raise event="ev.prev" />
<else/>
<raise event="ev.next" />
</if>
</if>
</onentry>
<transition event="ev.next" target="end" />
<transition event="ev.prev" target="state1" />
</state>
...
</state>
</scxml>
It works ok but when I have added the onentry element the proccessor says the following:
[WARN] Ignoring element <raise> in namespace "http://www.w3.org/2005/07/scxml" at null:2:882 and digester match "scxml/state/state/onentry/if/if/raise"
[WARN] Ignoring element <raise> in namespace "http://www.w3.org/2005/07/scxml" at null:2:912 and digester match "scxml/state/state/onentry/if/if/else/raise"
It seems that raise is not understood. I've tried to change 'raise' element with the 'send' one and I've gotten a similar log warning. Can anyone tell me what may be wrong?
Thanks.
UPDATE
I've tried to change the schema avoiding the embedding of the if elements like this:
<?xml version="1.0" encoding="utf-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initialstate="global">
...
<state id="global" initial="init">
...
<state id="state2">
<onentry>
<if cond="mydata.skip and _event.name=='ev.prev'">
<raise event="ev.prev" />
<else if cond="mydata.skip and _event.name=='ev.next'"/>
<raise event="ev.next" />
</if>
</onentry>
<transition event="ev.next" target="end" />
<transition event="ev.prev" target="state1" />
</state>
...
</state>
</scxml>
but it gives the following error too:
[WARN] Ignoring element <raise> in namespace "http://www.w3.org/2005/07/scxml" at null:2:1057 and digester match "scxml/state/state/onentry/if/raise"
I couldn't make the raise event work either. But according to the standard:
http://www.w3.org/TR/scxml/#raise
you can also use a send event. So I tried that, and I could make that work.
<state id="testID">
<onentry>
<send event="'test.onentry'" />
</onentry>
<transition event="test.transition" target="testID2"></transition>
</state>
That sent the event test.onentry as expected. But note the single quotes inside the double quotes in there!