Deprecated: Creation of dynamic property wpdb::$categories is deprecated in /home2/learnera/public_html/tech/wp-includes/wp-db.php on line 760

Deprecated: Creation of dynamic property wpdb::$post2cat is deprecated in /home2/learnera/public_html/tech/wp-includes/wp-db.php on line 760

Deprecated: Creation of dynamic property wpdb::$link2cat is deprecated in /home2/learnera/public_html/tech/wp-includes/wp-db.php on line 760

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home2/learnera/public_html/tech/wp-includes/comment-template.php on line 1747

Deprecated: Creation of dynamic property WPtouchProFour::$settings_object is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/wptouch/core/class-wptouch-pro.php on line 82

Deprecated: Automatic conversion of false to array is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/wptouch/core/admin-load.php on line 70

Deprecated: Creation of dynamic property WP_Block_Type::$skip_inner_blocks is deprecated in /home2/learnera/public_html/tech/wp-includes/class-wp-block-type.php on line 391

Deprecated: Creation of dynamic property WP_Block_Type::$skip_inner_blocks is deprecated in /home2/learnera/public_html/tech/wp-includes/class-wp-block-type.php on line 391

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_classic_block is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 347

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 349

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block_side is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 350

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$panels_block is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 351

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$used_block_buttons is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 354

Deprecated: Creation of dynamic property YARPP::$is_custom_template is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/yet-another-related-posts-plugin/classes/YARPP_Core.php on line 56

Deprecated: Creation of dynamic property YARPP::$db_options is deprecated in /home2/learnera/public_html/tech/wp-content/plugins/yet-another-related-posts-plugin/classes/YARPP_Core.php on line 69

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home2/learnera/public_html/tech/wp-includes/class-wp-term-query.php on line 1118

Deprecated: Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Cookie/Jar.php on line 63

Deprecated: Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Cookie/Jar.php on line 73

Deprecated: Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Cookie/Jar.php on line 89

Deprecated: Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Cookie/Jar.php on line 102

Deprecated: Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Cookie/Jar.php on line 111

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 40

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 51

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 68

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 82

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/learnera/public_html/tech/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 91

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723

Warning: Cannot modify header information - headers already sent by (output started at /home2/learnera/public_html/tech/wp-includes/wp-db.php:760) in /home2/learnera/public_html/tech/wp-includes/rest-api/class-wp-rest-server.php on line 1723
{"id":646,"date":"2018-04-17T15:42:20","date_gmt":"2018-04-17T15:42:20","guid":{"rendered":"http:\/\/tech.learnerandtutor.com\/?p=646"},"modified":"2020-05-18T04:06:56","modified_gmt":"2020-05-18T04:06:56","slug":"spring-web-flow-concepts-part-1","status":"publish","type":"post","link":"https:\/\/tech.learnerandtutor.com\/spring-web-flow-concepts-part-1\/","title":{"rendered":"Spring Web Flow – Concepts [Part 1]"},"content":{"rendered":"

In this post we will see the major concepts relates to Spring web flow. Spring flow is an approach to implement multi page flow web applications like shopping portal.\u00a0 For example in shopping portal application a user may involve in the below steps.<\/p>\n

    \n
  1. Login to the application<\/li>\n
  2. Surf among the products<\/li>\n
  3. Add needed products to the cart<\/li>\n
  4. view\/edit cart if needed<\/li>\n
  5. Click checkout<\/li>\n
  6. Provide contact information<\/li>\n
  7. Payment<\/li>\n
  8. End<\/li>\n<\/ol>\n

    As there are multiple pages involved in the shopping flow, the data needs to be carried throughout multiple pages. If we handle this task manually it will be tedious task. We will go out of our indented business logic. To implement these kinds of tasks easily Spring provides the web flow framework.<\/p>\n

    A flow is nothing but a set of tasks to be done in a particular order. In webflow it is an xml file which tells the exactly how this flow should works. If we configure our application flow in spring web flow, the data carrying portion as well as the page navigation issues will be taken care by spring web flow itself. We can concentrate on our business logic rather than spending time on working those mundane tasks.<\/p>\n

    Spring web flow can be configured only via xml file. Currently it is not feasible to configure via only java.<\/p>\n

    The first thing to setup a web flow is configuration. A flow configuration involves below major components. Let’s go through them.<\/p>\n

    Flow executor:\u00a0<\/strong>Flow executor is responsible to drive the flow.\u00a0 The syntax will be like below.<\/p>\n

    <flow:flow-executor id=\"flowExecutor\"\/><\/pre>\n

    Flow Registry:\u00a0<\/strong>Flow registry is responsible to load the flow definitions. For example if all flows under folder\u00a0WEB-INF\/flows<\/span>\u00a0needs to be loaded it has to be configured like\u00a0 below.<\/p>\n

    <flow:flow-registry id=\"flowRegistry\" base-path=\"\/WEB-INF\/flows\">\n<flow:flow-location-pattern value = \"**\/*-flow.xml\"\/> \n<\/flow:flow-registry><\/pre>\n

    Here one important thing to note is the url path to the flow will be determined by the path of the flow location.\u00a0 For example if the path of a flow is\u00a0\/WEB-INF\/flows\/order\/order-flow.xml<\/span>\u00a0 then the id will be order<\/span>\u00a0 (relative to the base path.) So the flow will be triggered while accessing the url http:\/\/{url}\/{contextpath}\/order<\/span><\/p>\n

    Instead of the pattern the path of the flow file also can be configured. For example to load\u00a0order-flow.xml<\/span>\u00a0flow it can be configured like below.<\/p>\n

    <flow:flow-registry id=\"flowRegistry\"> <flow:flow-location path = \"\/WEB-INF\/flows\/order\/order-flow.xml\"\/> <\/flow:flow-registry><\/pre>\n

    If the full path is specified then the filename will become the id of that flow. In the above case it will be order-flow<\/span>\u00a0. If id needs to be different from the path it can be specified with id attribute like below.<\/p>\n

    <flow:flow-location path = \"\/WEB-INF\/flows\/order\/order-flow.xml\" id=\"custom\/path\/flow\"\/><\/pre>\n

    As per the above code the flow will be triggered when the url {contextPath}\/custom\/path\/<\/span>\u00a0flow is entered.<\/p>\n

    Flow Handler Mapping :\u00a0<\/strong>Like DispatcherServlet<\/span>\u00a0 for controller mapping, there is a class FlowHandlerMapping<\/span>\u00a0 for URL to flow mapping for web flow.<\/p>\n

    Flow Handler Adapter :\u00a0<\/strong>Like Controllers for handling the requests, there is a class FlowHandlerAdapter<\/span>\u00a0 to handle the flow requests<\/p>\n

    The next important thing is the flow.\u00a0\u00a0A Flow is an xml file which tells the exactly how this flow should works. A flow will have three major components.<\/p>\n

      \n
    1. State<\/li>\n
    2. Transition<\/li>\n
    3. Data<\/li>\n<\/ol>\n

      State :\u00a0<\/strong>As per the name it is the state of the flow, which means the flows should be in a state.\u00a0 There are five types of states possible.<\/p>\n

        \n
      1. View-state<\/strong>\n
          \n
        • To display some pages to the user<\/li>\n
        • <view-state id=”welcome”\/><\/span>\u00a0will\u00a0redirect to the view named welcome<\/span><\/li>\n
        • <view-state id=”welcome” view=”success”\/><\/span>\u00a0will\u00a0redirect to the view named\u00a0success<\/span><\/li>\n
        • <view-state id=”welcome” view=”success” model=”flowScope.paymentDetails”\/><\/span>\u00a0will\u00a0redirect to the view named\u00a0\u00a0success<\/span>\u00a0 with model attribute paymentDetails<\/span>\u00a0

          <\/li>\n<\/ul>\n<\/li>\n
        • Action-state<\/strong>\n
            \n
          • To execute logical conditions. The syntax will be like below.\n
            <action-state id=\"saveOrder\">\n    <evaluate expression=\"pizzaFlowActions.saveOrder(order)\"\/>\n    <transition to=\"thankYou\"\/>\n<\/action-state><\/pre>\n<\/li>\n
          • When flow reaches\u00a0 the above state the method\u00a0pizzaFlowActions.saveOrder(order)<\/span>\u00a0 will be executed and once done thankYou<\/span>\u00a0 state will be invoked.<\/li>\n<\/ul>\n<\/li>\n
          • Decision-state<\/strong>\n