• Hallo Jürgen • Hallo Martin, hier ist Jürgen • Hallo Jürgen, hier ist Martin, gehen wir heute auf ein Bier • Hallo Martin, hier ist Jürgen, du fragtest, ob wir auf ein Bier gehen wollen, wohin denn? • Hallo Jürgen, hier ist Martin, ich habe dich gefragt ob wir auf ein Bier gehen wollen, du hast gefragt wohin denn, ich schlage vor, in den Wissensturm. • Hallo Martin, hier ist Jürgen, du fragtest, ob wir auf ein Bier gehen wollen, ich fragte, wohin du gehen wolltest, du hast vorgeschlagen, in den Wissensturm, ich sage ok, um 20:00.
in/complete communication? • Kommt auf den Anwendungsfall an • in (komplexeren) Webanwendungen ist häufig der Transfer zu aufwändig • context-complete communication schwierig • –-> State ist notwendig
state oder client- side state? • beides argumentierbar • client-seitiger State skaliert besser, stellt höhere Anforderungen an Client • server-seitiger State ist sicherer, stellt höhere Anforderungen an Server
• none (prototype) – bei jedem Zugriff neue Instanz • request – während einem Request dieselbe Instanz • session – während einer Session die selbe Instanz • application (singleton) – für die gesamte Anwendung dieselbe Instanz
• Scope startet, wenn eine Seite das erste mal angezeigt wird • Daten bleiben solange vorgehalten, wie mit der Seite interagiert wird • z.B. AJAX-Calls
Scope • Zwei Interpretationsvarianten: • Daten bleiben erhalten, wenn sie beim letzten Request/Response-Zyklus – gesetzt (etwas kurzlebiger als View-Scope, hilft z.B. für POST/REDIRECT Pattern) – noch verwendet wurden (etwas langlebiger als der View-Scope)
• Startet meistens automatisch, wenn erstmals verwendet • Oder manuell über Interaktion Entwickler/Conversation-Scope System • Schliesst meistens manuell über Interaktion Entwickler/Conversation-Scope System
ist das nicht in der Servlet-Spec? • Es gibt keinen Window-Identifier in der HTTP-Spec • Für Window/Tab-Demarkation benötigt man eine ordentliche Ladung JavaScript • Eine Implementierung war nicht "standardisierungsreif"
und Conversation • Spring-Webflow: jeder Zyklus entspricht einem Snapshot der Conversation • vor/zurück: entspricht weiter/zurückgehen in der Snapshothistory
in der Konfiguration <bean class= "org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="conversation.manual"> <bean class="org.apache.myfaces.orchestra.conversation.spring. SpringConversationScope" /> </entry> <entry key="conversation.access"> <bean class="org.apache.myfaces.orchestra.conversation.spring. SpringConversationScope"> <property name="lifetime" value="access" /> </bean> </entry> </map> </property> </bean> Den gewählten Scope Namen verwendet man dann in der Bean Deklaration (z.B.: scope=“conversation.access“).
Gleicher Conversation Name bedeutet gleiche PersistenceContext <beans ... xmlns:orchestra="http://myfaces.apache.org/orchestra" xsi:schemaLocation="... http://myfaces.apache.org/orchestra http://myfaces.apache.org/orchestra/orchestra.xsd"> <bean id=“sampleConversation" class="e..m..SampleBean" scope="conversation.manual“ /> <bean id="anotherBean" class="e...m...ExampleBean" scope="conversation.manual" orchestra:conversationName=“sampleConversation“ /> </beans> Beide Beans befinden sich in der selben Conversation. Der Name der Bean wird auch für die Conversation verwendet, wenn nichts anderes angegeben wurde.
sobald man Zugriff auf die Conversation hat – conversation.setAttribute(key, value) – conversation.hasAttribute(key) – conversation.getAttribute(key) – conversation.removeAttribute(key)
– vgl. BeanFactoryAware oder BeanNameAware Beans im Conversation Scope bekommen die Conversation, in der sie sich befinden, injiziert Injection erfolgt nach dem Auflösen der Dependencies, aber vor weiterer Initialisierung (init-method oder afterPropertiesSet())
implements ConversationAware { private Conversation conversation; /** * Setzt die Conversation, in der sich diese Bean befindet. */ public void setConversation(Conversation conversation) { this.conversation = conversation; } // ... }
Conversation hinzugefügt oder – von der Conversation entfernt wurde Vergleichbar mit javax.servlet.http. HttpSessionBindingListener import o..ap..m..orchestra.conversation.ConversationBindingListener; public class SampleBean implements ConversationBindingListener { public void valueBound(ConversationBindingEvent event) { /* .. */ public void valueUnbound(ConversationBindingEvent event) { /* .. *
zu beenden <%@ taglib uri="http://myfaces.apache.org/orchestra" prefix="o" %> ... <h:commandButton action="#{controller.process}" value=""> <o:endConversation name="conversation1" onOutcome="end,close,exit" /> <o:endConversation name="conversation2" /> </h:commandButton> Conversation wird auf jeden Fall beendet, egal welchen Outcome die Action liefert. Conversation wird beendet, wenn der Outcome der Action entweder „end“, „close“ oder „exit“ ist. Der Name der Conversation muss angegeben werden.
standardmäßiger Intervall: 5 Minuten – konfigurierbar über Parameter in der web.xml Letzter Zugriff auf Conversation entscheidend – standardmäßig gibt es kein Timeout – konfigurierbar in der Spring Konfiguration Achtung: Conversation Timeout sollte nicht kleiner sein als der Überprüfungsintervall
Conversation Timeout (2) <context-param> <description> Gibt den Intervall für die Überprüfung der Conversation Timeouts an (in ms). </description> <param-name> org.apache.myfaces.orchestra.WIPER_THREAD_CHECK_TIME </param-name> <param-value>60000</param-value> </context-param> <bean class="o.a.m.orchestra.conversation.spring.SpringConversationScope"> <!-- Timeout in Minuten --> <property name="timeout" value="35" /> ... </bean>
ist eine Anordnung von sog. States – State kann z.B. definieren, welche Informationen vom Benutzer benötigt werden oder – was mit diesen Informationen getan werden soll Quelle: http://springframework.org/webflow
Flows steht im Mittelpunkt von Spring Web Flow – Flow erstreckt sich meist über mehrere Requests – Flow gibt Abwicklung eines Geschäftsprozesses vor z.B. das Kaufen eines Produkts: Suche, Warenkorb, etc. Domain-Specifc Language für Flow Definition – Sowohl über XML als auch über eine Java API → Flow Definition ist sozusagen der Bauplan für einen Dialog mit dem User
xsi:schemaLocation=" http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow- 1.0.xsd"> <!–- View-States des Flows angeben --> <view-state id="[stateId]" view="[viewId]"> <!-- Transitions zwischen einzelnen States --> <transition ... /> </view-state> ... <!-- Ende des Flows markieren --> <end-state id="[stateId]" /> <end-state id="[stateId]" /> </flow> Es kann aber mehrere definierte Endpunkte für einen Flow geben. Der erste State gilt als Startpunkt des Flows.
> < v i e w - s t a t e i d = " s t a r t " . . . > . . . < / v i e w - s t a t e > < / f l o w > < s u b f l o w - s t a t e . . . > < / s u b f l o w - s t a t e > < s u b f l o w - s t a t e . . . > . . . < / s u b f l o w - s t a t e > C o n v e rs a tio n S c o p e F lo w S c o p e F lo w S c o p e F lo w S c o p e
<!–- View Scope: --> <view-state> <var name="viewPerson" class="at.irian.jsf.swf.example.Person" /> </view-state> </flow> Variables Beans können auch in den Flow Konfigurationen definiert werden – → mit dem „<var />“-Tag Serialisierbare Klasse mit einem Default-Konstruktor