Is there a way of using spring MVC contollers as subflows in spring webflow?
I have some data browsers written as plain MVC controllers and I would like to use them in my flows to browse/select data.
I managed to solve my problem. I am using a view state pointing to an external url (my controller). Here is the example:
<view-state id="itemBrowser" view="externalRedirect:contextRelative:/itemBrowser?callbackUrl=#{flowExecutionUrl}&itemSelectionMode=true">
<transition on="itemSelected" to="wizardStepBasic">
<evaluate expression="wizardActions.onItemSelected"/>
</transition>
</view-state>
The 'callbackUrl' parameter is used at the controller side to return to the flow. For example:
<a href=${callbackUrl}&selectedItemId=${item.id}&_eventId_itemSelected>
<img src="static/images/accept.png"/>
</a>
Hope, it'll be of some help to somebody :-)
Related
I am new to Spring Webflow and I am going through the codes and explanation on internet. I have a basic doubt regarding the flow of execution of codes in spring webflow applications.
As I have understood, A flow request is mapped to flow.xml file(I am now aware of FlowHandlerAdapter, FlowHandlerMapping, FlowRegistry). The starting state in the flow xml file, if it is a view-state, it renders a view.
For example -
<?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">
<secured attributes="ROLE_USER" />
<input name="hotelId" required="true" />
<on-start>
<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)" result="flowScope.booking" />
</on-start>
<view-state id="enterBookingDetails" model="booking">
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
<view-state id="reviewBooking">
<transition on="confirm" to="bookingConfirmed">
<evaluate expression="bookingService.persistBooking(booking)" />
</transition>
<transition on="revise" to="enterBookingDetails" />
<transition on="cancel" to="bookingCancelled" />
</view-state>
<end-state id="bookingConfirmed" />
<end-state id="bookingCancelled" />
</flow>
Here, when the flow file is being executed, the first view-state with id - "enterBookingDetails" renders the view enterBookingDetails.xhtml.
Does the control now go to the view page enterBookingDetails.xhtml and wait for the user event? And after the user clicks on button "proceed", the control comes back to flow XML file and executes the <transition> element to transit to reviewBooking view-state?
Am I understanding correctly that the flow execution is paused until a user event occurs, and upon occurrence of user event, control goes from web page to flow xml file and executes the transition and transits to corresponding state.
Yes, your understanding is essentially correct. Spring web flow framework renders the view, and then once the next action "proceed" is received, it will transit to the "reviewBooking" state, where again it would essentially pause until the next user action. Execution is based on transfer of state from one to another to complete the whole flow step-by-step.
NOTE : You may also re-use flows defined in other web-flow xml files in your own flow. This makes the framework very powerful.
I am new to the Spring Security module. I would like to know what is the difference between two security filters?
<security:intercept-url method="GET" pattern="/newapi/user/**" access="hasRole('ROLE_USER','LOW_ADMIN')" />
<security:intercept-url method="GET" pattern="/newapi/user/*/*" access="hasRole('ROLE_USER,'BIG_ADMIN')" />
Also it seems that first security filters blocking to execute the second filter, because when I'm executing /newapi/user/data/7897896, only first security filter excuting, but it was expected me to execute the second security filters. Could anyone tell me why it's happening and how we can solve such issues?
FYI - We've very big/huge web application, which has nearly 150+ security filters define , so it's really getting difficult to debug such security related issue. Any Spring Security expert(s) can we've your thoughts here?
The <intercept-url> rules are applied Top to Bottom. Therefore, this new should be place before the original one or else it will be eclipse by the broad scope of /** path, so that is the reason your 2nd security filter not executing. You need to change sequences like below
<security:intercept-url method="GET" pattern="/newapi/user/*/*" access="hasRole('ROLE_USER,'BIG_ADMIN')" />
<security:intercept-url method="GET" pattern="/newapi/user/**" access="hasRole('ROLE_USER','LOW_ADMIN')" />
I'm new to SWF (2.3.1), and am playing around to see if I can get something basic working. When I say 'basic', I really do mean basic. At this stage if I can possibly avoid it, I want to avoid writing any java. I just want to get a quick and dirty flow working, ideally all in the flow config.
I have managed to get a very basic linear flow working, going from view-state (screen?) A to B to C (AboutYou to AboutYourCar to YourQuote)
<?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">
<view-state id="AboutYou" view="/WEB-INF/views/jsp/motor/AboutYou.jsp">
<transition on="Next" to="AboutYourCar" />
</view-state>
<view-state id="AboutYourCar" view="/WEB-INF/views/jsp/motor/AboutYourCar.jsp">
<transition on="Back" to="AboutYou" />
<transition on="Next" to="YourQuote" />
</view-state>
<view-state id="Modifications" view="/WEB-INF/views/js/motor/Modifications.jsp">
<transition on="Back" to="AboutYourCar" />
</view-state>
<view-state id="YourQuote" view="/WEB-INF/views/jsp/motor/YourQuote.jsp">
<transition on="Back" to="AboutYou" />
</view-state>
</flow>
In the AboutYourCar view, I have an input field asking if the car has been modified:
Is your car modified?
<input type="radio" name="modified" value="No">
<input type="radio" name="modified" value="Yes">
What I would like to do is go to the Modifications view-state if the request parameter 'modified' is Yes; but I cant work out how to do this.
I think I would be able to get it working with an action-state, but (as I understand it) you need to provide an action bean which would perform some logic.
I also think I might be able to use a decision-state, but again, not really sure how I would write it.
Or maybe my whole approach is wrong, and that Modifications is not a view-state, but actually should be a sub-view??
Any help anyone could offer would be very much appreciated,
Thanks, Nathan
Something like:
<decision-state id="checkSelection">
<if test="requestParameters.modified == 'Yes'" then="Modifications" else="YourQuote"/>
</decision-state>
See Spring EL for what you can do with the Expression Language available within the flow configuration file (with or without your own Java objects) and EL Variables for the implicit variables available to Spring WebFlow.
I'm new to Webflow and am having an issue: I have some form objects which delegate to an underlying conversation scoped object (and thus modifying it when the form is bound on post). However, subsequent actions don't see the modifications - it appears when binding, the form is manipulating a different instance of the object than the one in the conversation scope.
Here is one of the view states that has this issue:
<view-state id="groupAccount" model="groupAccountForm" >
<on-entry>
<evaluate expression="enrollmentAction.createApplication()"
result="conversationScope.application" />
<evaluate expression="enrollmentAction.createGroupAccountForm(fapplication)"
result="viewScope.groupAccountForm" />
</on-entry>
<transition on="cancel" to="finish"></transition>
<transition on="continue" to="employee">
<!-- <evaluate
expression="groupAccountForm.getApplication()" result="conversationScope.application" /> -->
<evaluate
expression="enrollmentAction.save(application)" />
</transition>
</view-state>
On entry, I create my conversation scoped object and then create the form bean passing it. When the page is submitted, the binding works just fine however, the application passed to enrollmentAction.save(..) doesn't have the values from the page. The commented out line above it solves the issue but there's got to be a better way of handling this.
This is running on Jetty 6.1, it's a prototype so no authenticated user.
Just getting the hang of Spring Webflow. I have some simple forms working and binding back and forth - very cool. One thing not obvious to me at the moment is how to dynamically launch a flow based on user input.
i.e. imagine a flow where the user chooses an option in the first screen, and based on the choice taken, different subflows can be initiated. In pseudo-terms something like the following pseudo-flow:
<view-state id="selectService" model="serviceType">
<transition on="proceed">
<if "serviceType.selectedValue==1" to="subFlow1" />
<if "serviceType.selectedValue==2" to="subFlow2" />
<if "serviceType.selectedValue==3">
<if "serviceType.isValid==3" to="subFlow3" />
</if>
<default to="cancel" />
</transition>
<transition on="cancel" to="cancel" />
</view-state>
I've trawled the examples, docs, stackoverflow and the spring forums but haven't seen this anywhere..
It is covered in Spring in Action 3, which is a great book for Spring development in my eyes.
To answer your question here though, I think you are looking for the decision-state transition element. To get to user input, you should be able to use Spring Expression Language (SpEL) in the test attribute.
I tried using the decider recently, but frankly, for any non-trivial logic, it's best to move it to a Java method where you can easily unit test it. Then call said method and use the output from there. It's best to keep the flow XML files as simple as you can.