Einführung in Spring Web Flow

Erstellen Sie Ihre REST-API mit Spring – VIDEO-Kursen

Sie müssen festgestellt haben, dass Webanwendungen immer komplexer werden und ihre Wartung immer schwieriger wird. Sie müssen nun große und komplexe Seitenflüsse (Anwendungsfluss) schreiben oder verstehen und verwalten. Wenn Sie Schwierigkeiten haben, eine solch komplexe Anwendung zu erstellen, liegt die Antwort in der Verwendung von Spring Web Flow. Spring Web Flow (SWF) ist eine Komponente des Web-Stacks des Spring Framework, die sich auf die Definition und Ausführung des Benutzeroberflächenflusses (UI) innerhalb einer Webanwendung konzentriert. Es handelt sich um ein Modul, mit dem Sie logische Abläufe Ihrer Webanwendung erstellen können.

lesen Sie auch:

  • Frühlings-Tutorials
  • Frühling 4-Tutorials
  • Fragen zum Frühlingsinterview

Spring Web Flow ist bislang die beste Lösung für die Verwaltung von Webanwendungen mit komplexem Seitenfluss. Es
Bietet einen leistungsstarken Controller zur Steuerung der Benutzernavigation, falls Ihre Anwendung dies erfordert

Zum Beispiel:

Eine Beispieldefinition eines einfachen Ablaufs zur Durchführung eines Suchvorgangs ist unten grafisch dargestellt:

Abbildung 1 – Ein Beispiel für einen Suchablauf

Warum Spring Web Flow

Wir wissen, dass es schwierig ist, den Seitenfluss einer komplexen Webanwendung zu definieren und zu verstehen, unabhängig davon, auf welchem ​​Framework sie basiert. Für eine Struts-Anwendung müssen Sie eine Aktion schreiben, um jede Anfrage zu bearbeiten und zu verarbeiten. Dieser Ansatz mag für einfachere Anwendungen einfach sein, stellt sich jedoch vor, wenn Sie eine Anwendung damit schreiben würden

Bei komplexen Pfaden oder Prozessabläufen mit einer großen Anzahl von Ansichten wäre die Aufgabe mit dem herkömmlichen Ansatz schwierig. Die Wartung einer solchen Anwendung ist eine weitere mühsame Aufgabe. Sie müssen sich in den Code vertiefen, um den Prozessablauf der Anwendung zu verstehen. Dieses Problem verschlimmert sich erheblich, je größer und komplexer eine Webanwendung wird. In gewisser Weise verbergen diese Basismodell-2-Frameworks den übergeordneten Fluss, was es schwierig macht, den Lebenszyklus des Seitenflusses zu verfolgen.

Die Lösung bietet hier der Spring Web Flow. Mit Spring Web Flow können Sie die Seitenflüsse Ihrer Anwendung klar und einfach darstellen. Das Gute daran ist, dass Sie Spring Web Flow mit anderen Frameworks wie Struts, Spring und JSF verwenden können.

Vorteile von Spring Web Flow:

  • Der Seitenfluss der Anwendung ist bereits durch einen Blick auf die XML- oder Java-Konfiguration sichtbar.
  • Webflüsse sind eigenständig konzipiert und daher mehrfach wiederverwendbar.
  • Die Technik zur Erfassung des Seitenflusses bleibt in allen Fällen gleich und es gibt keine speziellen Ansätze für bestimmte Situationen.

Wie funktioniert Spring Web Flow?

Spring Web Flow besteht aus einer Reihe von Zuständen (Anzeigen einer Ansicht oder Ausführen einer beliebigen Aktion usw.). Der Übergang des Flusses von einem Zustand in einen anderen wird durch ein Ereignis ausgelöst. Dies wird fortgesetzt, bis der Fluss abgeschlossen ist und in den Endzustand eintritt. Die wichtigen Spring Web Flow-Zustände sind:

  • Der Startstatus: Wenn ein Flow erstellt wird, wird der Anfangsstatus des Flows durch das Startstatus-Attribut im Webflow definiert.
  • Ein Aktionszustand führt eine Aktion aus und gibt nach Abschluss ein logisches Ergebnis zurück. Der nächste Status, zu dem der Flow übergeht, hängt vom Ergebnis dieses Status ab. Wenn ein Ansichtsstatus eingegeben wird, wird der Flow angehalten und die Steuerung an den Client/Benutzer zurückgegeben. Der Flow wird bei dem Benutzer-/Client-Ereignis wieder aufgenommen, das den Flow wieder aufnimmt und löst den Übergang in den Zustand abhängig von der Benutzer-/Client-Eingabe oder -Entscheidung aus.
  • Ein Entscheidungszustand wird verwendet, um den nächsten Zustand dynamisch oder zur Laufzeit zu bestimmen. Wenn unser nächster Status von einigen Attributen oder Eigenschaften abhängt (z. B. wenn Benutzer nicht angemeldet sind, leiten Sie sie zur Anmeldeseite weiter).
  • Ein Subflow-Zustand wird verwendet, um unabhängige Flüsse darzustellen, die nicht vom Hauptfluss abhängig sind. Ein Unterfluss wird als untergeordnetes Element des Hauptflusses (übergeordneter Fluss) erstellt. Wenn ein untergeordneter Fluss aufgerufen wird, wird der übergeordnete Fluss angehalten, bis der untergeordnete Fluss abgeschlossen ist. Dies hilft dabei, die Anwendung als eine Reihe von Untermodulen (Subflows) zu verwalten, die mehrfach verwendet werden können. Der Subflow kann einem anderen Subflow oder dem Root-Flow untergeordnet sein.
  • Der Endzustand bedeutet das Ende des Flusses. Wenn ein Flow in den Endzustand eintritt, wird die aktive Flow-Sitzung beendet. Wenn der Endstatus des Root-Flows erreicht wird, werden die damit verbundenen Ressourcen automatisch bereinigt.
  • Werfen wir einen Blick auf einen Beispiel-Webablauf für den Prozessablauf bei der Buchung von Kinokarten. Das UML-Zustandsdiagramm dafür finden Sie unten.

    Figur 2 Ablauf der Kinokartenbuchung in UML

    Der folgende XML-Code demonstriert diesen Webfluss.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
    
            "http://www.springframework.org/dtd/spring-webflow.dtd">
    
    <webflow id="bookticket" start-state="obtainMovieInfo">
    
            <action-state id="obtainMovieInfo">
    
                   <action bean="bookingActions" method="bindAndValidate"/>
    
                   <transition on="success" to="availableShows"/>
    
                   <transition on="error" to="tryAgain"/>
    
            </action-state>
    
            <action-state id="availableShows">
    
                   <action bean="bookingActions"/>
    
                   <transition on="success" to="displayShowTimings"/>
    
            </action-state>
    
            <view-state id="displayShowTimings" view="showTimings">
    
                   <transition on="startOver" to="cancel"/>
    
                   <transition on="select" to="selectShow"/>
    
            </view-state>
    
            <action-state id="selectShow">
    
                   <action bean="bookingActions"/>
    
                   <transition on="success" to="isPersonalInfoRequired"/>
    
            </action-state>
    
            <decision-state id="isPersonalInfoRequired">
    
                   <if test="${requestScope.person == null}" then="enterPersonalInformation"/>
    
                   <if test="${requestScope.person.preferences.alwaysConfirmPersonalInfo}"
    
                           then="enterPersonalInformation" else="displayReservationVerification"/>
    
            </decision-state>
    
            <subflow-state id="enterPersonalInformation" flow="person">
    
                   <attribute-mapper>
    
                           <input value="${requestScope.person.id}" as="personId"/>
    
                   </attribute-mapper>
    
                   <transition on="finish" to="displayReservationVerification"/>
    
            </subflow-state>
    
            <view-state id="displayReservationVerification" view="reservationVerification">
    
                   <transition on="startOver" to="cancel"/>
    
                   <transition on="assignSeats" to="chooseSeatAssignments"/>
    
                   <transition on="book" to="book"/>
    
            </view-state>
    
            <subflow-state id="chooseSeatAssignments" flow="seatAssignments">
    
                   <attribute-mapper>
    
                           <input value="${requestScope.person.id}" as="personId"/>
    
                           <input name="show"/>
    
                   </attribute-mapper>
    
                   <transition on="finish" to="displayReservationVerification"/>
    
            </subflow-state>
    
            <action-state id="book">
    
                   <action bean="bookingActions"/>
    
                   <transition on="success" to="displayConfirmation"/>
    
            </action-state>
    
            <end-state id="displayConfirmation" view="reservationConfirmation"/>
    
            <end-state id="tryAgain" view="tryAgain"/>
    
            <end-state id="cancel" view="home"/>
    
    </webflow>

    Allein anhand des Aussehens dieser XML-Datei können Sie den logischen Ablauf (Prozessablauf) der Anwendung verstehen, auch ohne einen Blick auf andere Teile des Codes zu werfen. In der obigen XML-Definition können Sie sehen, dass der Webflow Unterflüsse enthält. Diese Unterflüsse können als Module Ihrer Anwendung fungieren und sind wiederverwendbar. Dies ist die vorteilhafteste Eigenschaft von Spring Web Flow

    XML-Definition erklärt

    Schauen wir uns jede Komponente der obigen XML-Definition in Spring Web Flow an.

    Die Flow-Definition

    Beginnend mit Zeile 1 der XML-basierten Flussdefinition:

    <webflow id="bookticket" start-state="obtainMovieInfo">
    
            ...
    
    </webflow>

    <webflow id="bookticket" start-state="obtainMovieInfo">
    
            ...
    
    </webflow>

    Das Webflow-Element definiert den Fluss und gibt seine ID und seinen Startstatus an. Die ID ist eine eindeutige Kennung. Wenn eine neue Flow-Sitzung aktiviert wird, ist der Startstatus der erste Status, in den der Flow bei Erfolg übergeht. Wenn hier also eine neue Sitzung für bookticket aktiviert wird, lautet der erste Status „recoverMovieInfo“. Jetzt in der Statusdefinition „recoverMovieInfo“.

    <action-state id="obtainMovieInfo">
    
            <action bean="bookingActions" method="bindAndValidate"/>
    
            <transition on="success" to="availableShows"/>
    
            <transition on="error" to="tryAgain"/>
    
    </action-state>

    Dies ist ein Aktionszustand, der bei der Ausführung ein logisches Ergebnis zurückgibt. Wenn der Fluss also in diesen Geschäftsfall eintritt (obtainMovieInfo), wird die bindAndValidate-Methode mit der bookingActions-Kennung aufgerufen. Wenn dieser Vorgang erfolgreich ist, wird der Status „availableShows“ eingegeben, andernfalls wird der Status „tryAgain“ eingegeben.

    Die Buchungsaktion

    Bei Verwendung von Spring Web Flow mit Spring sieht die bookingActions-Bean-Definition in web-context.xml wie folgt aus:

    web-context.xml
    
    <bean id="bookingActions"
    
     >
    
        <property name="bookingAgent" ref="myBookingAgent"/>
    
    </bean>

    Auf diese Weise wird unsere Aktion über die Abhängigkeitsinjektion über Spring verwaltet und konfiguriert.

    Der Aktionsstatus „Verfügbar“ wird angezeigt

    Kommen wir nun zum nächsten Aktionszustand:

    <action-state id="availableShows">
    
            <action bean="bookingActions"/>
    
            <transition on="success" to="displayShowTimings"/>
    
    </action-state>

    Hier übergeben wir das validierte Movie-Objekt als Eingabe und es gibt eine Sammlung von Show-Timings zurück. Der eigentliche Code sieht so aus:

    public class BookingActions extends FormAction {
        ...
    
        public Event availableShows(RequestContext context) {
    
            Movie movie = (Movie)context.getRequestScope().getAttribute("movie");
    
            Collection<ShowTimings> showTimings = bookingAgent.availableShows(movie);
    
            context.getRequestScope().setAttribute("showTimings", showTimings);
    
            return success();
    
        }
    
    }

    Die Methode „availableShows“ wird aufgerufen, wenn der Flow in den Status „availableShows“ wechselt. Dies gilt allgemein für alle Staaten. Wenn ein Status eingegeben wird, wird eine Methode für die Ziel-Action-Bean aufgerufen. Und bei erfolgreicher Ausführung dieser Methode wird die showTimings-Sammlung zurückgegeben und der Status wird in die displayShowTimings-Ansicht geändert

    Anzeige Status der Timings-Ansicht anzeigen

    In dieser Ansicht werden alle verfügbaren Shows für diesen Film angezeigt (aus der Show-Timings-Sammlung).

    <view-state id="displayShowTimings" view="showTimings">
    
            <transition on="startOver" to="cancel"/>
    
            <transition on="select" to="selectShow"/>
    
    </view-state>

    Dies ist ein Ansichtsstatus und der Fluss wird für die Benutzerantwort angehalten. Hier kann der Benutzer entweder auswählen oder von vorne beginnen. Bei einem Select-Ereignis wechselt der Flow in den SelectShow-Status und bei StartOver wechselt der Flow in den Abbruchstatus, abhängig von der Benutzereingabe.

    Clientseitiger Status

    Auf der Clientseite wird die ID des ausführenden Flows verfolgt und die Eingabewerte für das nächste Ereignis werden ebenfalls über diese ID bereitgestellt.

    Zum Beispiel in einem JSP:

    <input type="hidden" value="<c:out value="${flowExecution.id}"/>">

    Die Frage „Sind personenbezogene Daten erforderlich?“ wird angezeigt. Entscheidungsstaat

    Nachdem der Benutzer eine Show ausgewählt hat, muss der Ablauf abhängig vom Status des Benutzers eine dynamische Entscheidung treffen, wohin er als nächstes gehen soll. Wenn der Benutzer angemeldet ist, möchten Sie ihn möglicherweise zur Buchungsseite weiterleiten. Wenn er nicht angemeldet ist, möchten Sie möglicherweise, dass er seine Daten wie Name und Kreditkartennummer eingibt.

    Für diese dynamische Entscheidung verwenden wir den Entscheidungszustand. Nachfolgend finden Sie die Definition für den Entscheidungszustand:

    <decision-state id="isPersonalInfoRequired">
    
            <if test="${requestScope.person == null}" then="enterPersonalInformation"/>
    
            <if test="${requestScope.person.preferences.alwaysConfirmPersonalInfo}"
    
                   then="enterPersonalInformation" else="displayReservationVerification"/>
    
    </decision-state>

    persönlich Status des Informations-Subflows

    Die Pflege persönlicher Daten erfolgt unabhängig vom logischen Ablauf der Anwendung. Ein Mitarbeiter kann seine persönlichen Daten aktualisieren, ohne Tickets zu buchen. Für einen solchen unabhängigen Flussprozess können wir den Subflow-Status verwenden.

    Geben Sie persönliche Informationen ein

    Unterflussstatus:

    <subflow-state id="enterPersonalInformation" flow="person">
    
            <attribute-mapper>
    
                   <input value="${requestScope.person.id}" as="personId"/>
    
            </attribute-mapper>
    
            <transition on="finish" to="displayReservationVerification"/>
    
    </subflow-state>

    Das Attribute-Mapper-Element ordnet mithilfe der Attribut-ID Attribute dem und vom Subflow zu. Und wenn der Unterfluss abgeschlossen ist, wird die Kontrolle wieder an den übergeordneten Fluss zurückgegeben. Wenn in unserem Geschäftsfluss in den EnterPersonalInformation-Status eingetreten wird, wird der persönliche Fluss als untergeordnetes Element des aktuellen Flusses (in diesem Fall Webflow) erstellt. Das personId-Attribut wird als Eingabe an den untergeordneten Fluss übergeben und die Verarbeitung des untergeordneten Flusses ist von nun an bis zu seinem Abschluss unabhängig vom übergeordneten Fluss. Nach Abschluss des Unterflusses wird der übergeordnete Fluss fortgesetzt und bestimmt abhängig vom Ergebnis des untergeordneten Flusses, in welchen Zustand übergegangen werden soll.

    Der Endstatus der Anzeigebestätigung

    Nachdem eine Show erfolgreich gebucht wurde, endet unser Ablauf und wir möchten eine Bestätigung anzeigen. Siehe unten:

    <end-state id="displayConfirmation" view="reservationConfirmation"/>

    Dies ist der Endzustand und wenn der Bookticket-Flow in diesen Zustand eintritt, wird der Flow beendet und die Ressourcen werden zur Wiederverwendung bereinigt (dies ist ein automatischer Prozess in Spring Web Flow). Hinweis: Hätte der Endfluss als Unterfluss fungiert, wird der eingegebene Endstatus als a behandelt Unterfluss Ergebnis Der fortfahrende übergeordnete Fluss kann darauf reagieren. Genauer gesagt wird die eingegebene Endstatus-ID als Grundlage für einen Statusübergang im Subflow-Status des wiederaufnehmenden übergeordneten Flows verwendet. Sie können dies in Aktion sehen, indem Sie einen Blick auf die Subflow-Statusdefinition „enterPassengerInformation“ werfen. Beachten Sie, wie es auf das „Finish“-Ergebnis des Subflows reagiert, das einem „Finish“-Endzustand innerhalb des Passagierflusses entspricht.

    Flow-Bereitstellung

    Wir haben die Flow-Definition geschrieben und möchten sie jetzt mit unserer Spring-Anwendung verwenden. Alles was wir tun müssen ist.

    <bean name="/book.htm"SpellE" style="border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent; margin: 0px; padding: 0px;">org.springframework.web.flow.mvc.FlowController">
        <property name="flow">
            <ref bean="bookFlow"/>
        </property>
    </bean>
    
    <bean id="bookFlow"SpellE" style="border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent; margin: 0px; padding: 0px;">org.springframework.web.flow.config.XmlFlowFactoryBean">
       <property name="location" value="classpath:bookticket-flow.xml"/>
    </bean>
    

    Wann sollte Spring Web Flow verwendet werden?

    Spring Web Flow sollte in Anwendungen verwendet werden, bei denen der Benutzer eine kontrollierte Navigation haben soll und die Navigation komplex und der Prozessablauf umfangreich ist. Da Spring Web Flow zustandsbehaftet ist, eignet es sich gut für komplexe Geschäftsabläufe. Es sollte nicht in einfachen Anwendungen mit geringem Durchfluss oder bei denen eine zustandslose Lösung erforderlich ist, verwendet werden.

    Einige Beispiele, bei denen Spring Web Flow am besten geeignet wäre:

    • Tickets buchen
    • Online Einkaufen

    Schreiben Sie Ihre erste Anwendung mit Spring Web Flow:

    Vorausgesetzt, Sie verfügen über Grundkenntnisse in Spring, HTML und JSP, da wir Spring in unserer Anwendung verwenden werden, und natürlich müssen Sie HTML und JSP beherrschen. Zuerst müssen Sie Spring Web Flow und Spring Framework herunterladen (Sie können sie herunterladen von http://www.springframework.org/).
    Lasst uns anfangen.

    • Umgebungsvariablen festlegen: Ihr Klassenpfad sollte die Dateien spring-webflow-1.0.jar, spring-binding-1.0.jar und spring.jar enthalten.
    • Nachdem die Umgebung nun bereit ist, können wir unseren ersten Ablauf entwerfen. Wir entwerfen eine Login-Seite. Beim Start wird eine Formularansicht im Browser angezeigt. Beim Absenden validieren Sie die Formulareingabedaten und melden Sie den Benutzer an.
    • Wir können nun die Ablaufdefinition für unseren Anmeldeprozess erstellen.

    myFlow.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE flow PUBLIC "-//SPRING//DTD WEBFLOW 1.0//EN"
           "http://www.springframework.org/dtd/spring-webflow-1.0.dtd">
     <flow start-state="displayLoginForm">
         <view-state id="displayLoginForm" view="form">
            <entry-actions>
                <action bean="loginForm" method="setupForm"/>
            </entry-actions>
            <transition on="submit" to="processLogin">
                <action bean="loginForm" method="bindAndValidate"/>
            </transition>
        </view-state>
         <action-state id="processLogin">
            <action bean="loginForm" method="processLogin"/>
            <transition on="success" to="finish"/>
        </action-state>
         <end-state id="finish" view="success"/>
     </flow>
    

    MyLoginAction.java

    public class MyLoginAction extends FormAction {
        public MyLoginAction() {
            setFormObjectClass(FormObject.class);
        }
        public static class FormObject implements Serializable {
            private String user;
             private String password;
            public String getUser() {
                return user;
            }
            public void setUser(String user) {
                this.user = user;
            }
             public String getPassword(){
                return password;
            }
            public void setPassword(String password) {
                this.password = password;
            }
        }
        public Event processLogin(RequestContext context) throws Exception {
            FormObject formObject = (FormObject)getFormObject(context);
            // todo login logic
            return success();
        }
    }
    

    Jetzt werden wir unseren Flow mithilfe von Spring Application Context bereitstellen. Wir werden XmlFlowRegistryFactoryBean verwenden.

    „dispatcher-servlet.xml“.

    <bean id="flowRegistry"  >
       <property name="flowLocations" value="/WEB-INF/flows/myflow.xml"/>
    </bean>
    <bean id="formAction"  />
    

    Definieren Sie einen FlowController und ViewResolver:
    „dispatcher-servlet.xml“.

    <bean name="/myApp.htm"  >
        <property name="flowLocator" ref="flowRegistry"/>
    </bean>
     <!-- Maps flow view-state view names to JSP templates with JSTL support -->
    <bean id="viewResolver"  >
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    

    <html>
    <head>
       <title>My Login Page</title>
    </head>
    <body>
    <p>
       <table>
       <form action="myApp.htm">
           <tr>
               <td>User</td>
               <td><input type="text" name="user" size="25"/></td>
           </tr>
      <tr>
               <td>Password</td>
               <td><input type="text" name="password" size="25"/></td>
           </tr>
            <tr>
               <td colspan="2" align="right">
                   <input name="_eventId_submit" type="submit">
                   <input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
               </td>
           </tr>
       </form>
       </table>
    </p>
    </body>
    </html>
    

    Die Parameter _eventId und _flowExecutionKey sind erforderlich, damit die Ansicht an den Server übermittelt werden kann. _flowExecutionKey wird verwendet, um den Status des Flusses aufrechtzuerhalten. Auf diese Weise identifiziert der Server den aktuellen Fluss des Clients. _eventId wird verwendet, um zu signalisieren, welches Ereignis auf dem Client aufgetreten ist. In unserer Anmeldeanwendung wird „Senden“ gesendet, wenn die Schaltfläche „Senden“ gedrückt wird. Und abhängig von seinem Wert erfolgt der Flussübergang zum nächsten Schritt.

    lesen Sie auch:

    • Frühlingsbücher
    • Einführung in das Spring Framework
    • Einführung in das Spring MVC Framework

    Jetzt können wir unsere Anwendung bereitstellen und testen. Zum Testen unserer Anwendung lautet die URL /myApp.htm?_flowId=myFlow URL. Wenn wir auf diese URL zugreifen, wird eine neue „myFlow“-FlowExecution erstellt und in ihren Startstatus (displayLoginForm) überführt, und die nächsten Schritte folgen gemäß der myFlow-Flow-Definition.

    Abschluss

    Spring Web Flow ist die beste Lösung für die Verwaltung eines komplexen Geschäftsprozessablaufs. Darüber hinaus kann es in Ihre bestehende Umgebung wie Struts und JSF integriert werden. Also, worauf warten Sie noch? Holen Sie es sich.

    Kommentar verfassen

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

    Nach oben scrollen