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.
Related
I have a custom control that currently conditionally renders content:
<me:CustomControl>
<switch>
<if "expression is true">
<textbox id="Name" />
</if>
<if "expression is true">
...
</if>
<else>
<textbox id="Name" />
</else>
</switch>
</me:CustomControl>
My example above makes no logical sense, but gets straight to the point. The <if> tag is evaluated by overriding the GetChildControlType function. The <textbox> inside is evaluated in the <if>'s control builder.
What I want to do is completely remove the control from the collection, or even better yet, prevent child controls of <if> from being added to the collection to begin with. If I try to remove them OnInit, I still get the error "The ID 'Name' is already used by another control."
I can't evaluate them in the:
Public Overrides Function GetChildControlType(ByVal tagName... ) As Type
Because I need to perform logic on all the if's and else's within it.
Maybe there's a better way?
Update
I get a compilation error even if I break this thing down to bare bones if there are more than one controls with the same ID, even though overriding CreateChildControls. not sure if I can get around this at all.
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.
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 :-)