Jan Lantora
13.9.2017

Spring Web Flow a JSF

webflow_jsf

Hledali jste někdy vhodnou kombinaci frameworků, pro vývoj webové formulářové aplikace, která Vám umožní rychlou a snadnou implementaci? Zkuste Spring Web Flow s integrací JSF. V tomto článku si ukážeme jednoduché nastavení, jak tyto frameworky propojit.


Anotace


Have you ever looked for a suitable combination of frameworks to develop a web form application that will allow you quick and easy implementation? Try Spring Web Flow with JSF integration. In this article, we will show you how to easily integrate these frameworks.

Spring context


Nastavení Web Flow s JSF je možné pomocí XML konfigurace nebo Java konfigurace. První si ukážeme XML konfiguraci.

Propojení Web Flow a JSF vyžaduje definování JsfFlowHandlerAdapter na místo FlowHandlerAdapter, který se jinak pro Web Flow používá. To způsobí převedení requestů z Web Flow do podoby kterou je schopný zpracovat JSF listener.
Zároveň touto změnou dochází k nahrazení SpringJavaScriptAjaxHandler adaptérem JsfAjaxHandler.

<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

Pro vytvoření JsfFlowHandlerAdapter je nutné definovat Flow-Executor a Flow-Registry. Nejdříve si však musíme připravit namespace pro webflow a faces, s kterými budeme pracovat.

<beans
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"/>

Flow-Executor je vstupní bod do celého Spring Web Flow systému, provádí orchestraci všech flow a pomocí Flow-Registry rozhoduje o přechodech a provedených akcích. V rámci integrace s JSF navíc obsahuje FlowFacesContextLifecycleListener, který udržuje pro každý Web Flow request jednu instanci FacesContext.

<webflow:flow-executor id="flowExecutor"
flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>

<bean id="facesContextListener" class = "org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

Flow-Registry obsahuje cestu ke všem proveditelným flow definicím v systému, v našem pouze ke customer-search-flow.xml. Flow-Registry dále obsahuje Flow-builder-services, kde můžeme customizovat nastavení a vytváření všech flow, které se uloží do Flow-Registry.

<webflow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices">
<webflow:flow-location-pattern value="/WEB-INF/customer-search-flow.xml" />
</webflow:flow-registry>

<faces:flow-builder-services id="flowBuilderServices" />

Java konfigurace

Zde si ukážeme stejné nastavení pomocí Java konfigurace.

@Configuration
public class WebFlowConfig extends AbstractFacesFlowConfiguration {

@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry())
.addFlowExecutionListener(
new FlowFacesContextLifecycleListener())
.build();
}

@Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder(flowBuilderServices())
.addFlowLocationPattern("/WEB-INF/customer-search-flow.xml")
.build();
}

@Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder().setDevelopmentMode(true).
build();
}
}

Service

Teď když máme připravenou konfiguraci, se podíváme na malou ukázku, jak to celé funguje. V první řadě si připravíme Spring beanu, která bude mít metodu searchCustomers s parametrem searchString. Tuto metodu pak budeme volat z Web Flow.

CustomerService.java

public interface CustomerService {
List<Customer> searchCustomers(String searchString);

Máme připravenou beanu, kterou budeme volat. Pojďme definovat flow, v kterém ji použijeme. Flow je v zásadě posloupnost akcí, prováděných za účelem dokončení společného cíle v rámci kontextu. V závislosti na volbách uživatele mohou události přecházet mezi jednotlivými obrazovkami.

Flow

Ve flow připravíme proměnné a stavy. V proměnných si připravíme proměnnou pro hledaný řetězec, pokud neuvedeme scope. Pproměnné použije se Flow a proměnná tak bude existovat, dokud nezanikne flow, ve kterém byla registrována.
Stavy vytvoříme, aby odpovídalyi .xhtml stránkám, které vzniknou v rámci JSF. První view stav obsahuje přechod na druhý, pokud je vyvolána akce search. V druhém view stavu vždy při vykreslování obrazovky vyhodnocujeme výraz customerService.searchCustomers(searchString), kde customerService je spring beana registrovaná v aplikačním kontextu. Výsledek výrazu uložíme do proměnné customers, se scopem view. Bude tedy přístupná pouze v tomto view stavu.

customer-search-flow.xml

<var name="searchString" class="java.lang.String" />

<view-state id="searchCustomer">
<transition on="search" to="customerList"/>
</view-state>

<view-state id="customerList">
<on-render>
<evaluate expression="customerService.searchCustomers(searchString)"
result="viewScope.customers"/>
</on-render>
</view-state>

JSF stránky

Na závěr vytvoříme jednoduché JSF stránky. Pro snadné propojení s flow budou názvy stránek shodné s view stavy.

Na první stránce vytvoříme tlačítko, které bude provolávat akci search do flow.

customerSearch.xhtml

<h:form>
<h:panelGrid columns="2">
<h:outputLabel for="search">Search: </h:outputLabel>
<h:inputText id="search" value="#{searchString}" />
<p:commandButton id="find" value="Find" action ="search"
update="@form" />
</h:panelGrid>
</h:form>

Na druhé stránce zobrazíme seznam, který jsme získali ve flow a uložili ho do proměnné customers.

customerList.xhtml

<h:form>
<p:dataTable id="customers" var="customer" value="#{customers}">
<p:column>
<f:facet name="header">Name</f:facet>
#{customer.name}
</p:column>
<p:column>
<f:facet name="header">Surname</f:facet>
#{customer.surname}
</p:column>
</p:dataTable>
</h:form>

Závěr


Spring Web Flow je silný nástroj pro implementaci navigace a uchování aplikačního stavu, zejména při rychle se rozvíjejících aplikací. Jak jsme si ukázali, integrace s JSF je poměrně snadná a ve spojení s Web Flow vhodná pro rychlý vznik formulářových aplikací, které potřebují mít snadnou kontrolu nad přechody mezi formuláři.

Vaše emailová adresa nebude zveřejněna

Komentáře

Děkujeme za váš komentář
Další