From 34dbdb43223e0a3d90d85b9de8f95b39592baebc Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 28 Feb 2011 10:56:37 +0000 Subject: [PATCH] SWF-1447 2.3 documentation updates --- .../src/flow-managed-persistence.xml | 2 +- spring-webflow-reference/src/spring-faces.xml | 2092 +++++++++-------- spring-webflow-reference/src/spring-mvc.xml | 730 +++--- spring-webflow-reference/src/views.xml | 32 +- spring-webflow-reference/src/whatsnew.xml | 288 ++- 5 files changed, 1800 insertions(+), 1344 deletions(-) diff --git a/spring-webflow-reference/src/flow-managed-persistence.xml b/spring-webflow-reference/src/flow-managed-persistence.xml index 0f2259cd..752186fe 100644 --- a/spring-webflow-reference/src/flow-managed-persistence.xml +++ b/spring-webflow-reference/src/flow-managed-persistence.xml @@ -78,7 +78,7 @@ Flow Managed Persistence And Sub-Flows - Starting with version 2.3 a flow managed PersistenceContext is automatically extended + A flow managed PersistenceContext is automatically extended (propagated) to subflows assuming the subflow also has the <perstistence-context/> variable. When a subflow re-uses the PersistenceContext started by its parent it ignores commit flags when an end state is reached thereby deferring the final decision (to commit or not) to diff --git a/spring-webflow-reference/src/spring-faces.xml b/spring-webflow-reference/src/spring-faces.xml index c911211c..a820c9a5 100644 --- a/spring-webflow-reference/src/spring-faces.xml +++ b/spring-webflow-reference/src/spring-faces.xml @@ -1,201 +1,242 @@ +"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> - JSF Integration - - Introduction - - Spring Web Flow provides an integration that simplifies using with Spring. It lets you use the - JSF UI Component Model with Spring MVC and Spring Web Flow controllers. As of Spring Web Flow - 2.2 the JSF integration is supported with JSF 1.2 and JSF 2.0 including Sun Mojarra and Apache - MyFaces. Please, note however that JSF 2 partial state saving is not yet supported with - Apache MyFaces and needs to be disabled with the javax.faces.PARTIAL_STATE_SAVING - context parameter in web.xml. - - - Spring Web Flow provides a Spring Security tag library for JSF 2 and JSF 1.2 environments. - It provides an <authorize> tag as well as several EL functions. - See for more details. - - - A small Facelets component library that provides Ajax and client-side validation capabilities - in JSF 1.2 environments only is also shipped with Web Flow. Note that this library will not - be upgraded to JSF 2.0 in favor of 3rd party component libraries such as PrimeFaces - and RichFaces. The swf-booking-faces sample in the Spring Web Flow distribution - is built on JSF 2 and PrimeFaces components. - - - Spring Web Flow also supports using JSF in a portlet environment. - Spring Web Flow's portlet integration supports Portlets API 2.0 and JSF 1.2 only. - Currently JSF 2 is not supported in combination with portlets. - See for more on Spring Web Flow's portlet integration. - - - - JSF Integration For Spring Developers - - Spring Web Flow complements the strengths of JSF, its component model, and provides more sophisticated state management and navigation. - In addition you have the ability to use Spring MVC @Controller or flow definitions as controllers in the web layer. - - - JSF applications using Spring Web Flow applications gain benefits in the following areas: - - Managed bean facility - Scope management - Event handling - Navigation - Modularization and packaging of views - Cleaner URLs - Model-level validation - Progressivy-enhancement sytle client-side validation - Progressive-enhancement style Ajax requests with partial page updates - + JSF Integration - Using these features significantly reduce the amount of configuration required in faces-config.xml. - They provide a cleaner separation between the view and controller layers along with better modularization of application functionals. - These features are detailed in the sections to follow. - The majority of these features build on the flow definition language of Spring Web Flow. - Therefore it is assumed that you have an understanding of the foundations presented in . - - - - Configuring web.xml - - The first step is to route requests to the DispatcherServlet in the web.xml file. - In this example, we map all URLs that begin with /spring/ to the servlet. - The servlet needs to be configured. - An init-param is used in the servlet to pass the contextConfigLocation. - This is the location of the Spring configuration for your web application. - - - Spring MVC Dispatcher Servlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - /WEB-INF/web-application-config.xml - - 1 - + + Introduction + + Spring Web Flow provides a JSF integration that simplifies using JSF + with Spring. It lets you use the JSF UI Component Model with Spring MVC + and Spring Web Flow controllers. Along with the JSF integration Spring Web + Flow provides a small Facelets component library (called Spring Faces) for + use in JSF 1.2 environments and a Spring Security tag library for use in + both JSF 1.2 and JSF 2.0 environments (see for more details). + + Starting with version 2.2 the JSF integration in Web Flow supports + JSF 2.0 including Sun Mojarra and Apache MyFaces runtime environments. + Please, note however that JSF 2 partial state saving is not yet supported + with Apache MyFaces and needs to be disabled with the + javax.faces.PARTIAL_STATE_SAVING context parameter in + web.xml. + + Also note that the Spring Faces component library, which provides + Ajax and client-side validation capabilities is for JSF 1.2 environments + only and will not be upgraded to JSF 2.0. Applications are encouraged to + use 3rd party JSF 2 component libraries such as PrimeFaces and RichFaces. + The swf-booking-faces sample in the Spring Web Flow + distribution for example is built with JSF 2 and PrimeFaces + components. + + Spring Web Flow also supports using JSF in a portlet environment. + Spring Web Flow's portlet integration supports Portlets API 2.0 and JSF + 1.2 only. Currently JSF 2 is not supported in combination with portlets. + See for more on Spring Web Flow's portlet + integration. + + + + JSF Integration For Spring Developers + + Spring Web Flow complements the strengths of JSF, its component + model, and provides more sophisticated state management and navigation. In + addition you have the ability to use Spring MVC @Controller or flow + definitions as controllers in the web layer. + + JSF applications using Spring Web Flow applications gain benefits in + the following areas: + + Managed bean facility + + + + Scope management + + + + Event handling + + + + Navigation + + + + Modularization and packaging of views + + + + Cleaner URLs + + + + Model-level validation + + + + Progressivy-enhancement sytle client-side validation + + + + Progressive-enhancement style Ajax requests with partial page + updates + + Using these features significantly reduce the amount of + configuration required in faces-config.xml. They provide a cleaner + separation between the view and controller layers along with better + modularization of application functionals. These features are detailed in + the sections to follow. The majority of these features build on the flow + definition language of Spring Web Flow. Therefore it is assumed that you + have an understanding of the foundations presented in . + + + + Configuring web.xml + + The first step is to route requests to the + DispatcherServlet in the web.xml file. In this + example, we map all URLs that begin with /spring/ to the + servlet. The servlet needs to be configured. An init-param is + used in the servlet to pass the contextConfigLocation. This + is the location of the Spring configuration for your web + application. + + +<servlet> + <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> + <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> + <init-param> + <param-name>contextConfigLocation</param-name> + <param-value>/WEB-INF/web-application-config.xml</param-value> + </init-param> + <load-on-startup>1</load-on-startup> +</servlet> - - Spring MVC Dispatcher Servlet - /spring/* -]]> +<servlet-mapping> + <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> + <url-pattern>/spring/*</url-pattern> +</servlet-mapping> - - In order for JSF to bootstrap correctly, the - FacesServlet - must be configured in - web.xml - as it normally would even though you generally will not need to route requests through it at all when using JSF with Spring Web Flow. - - - - Faces Servlet - javax.faces.webapp.FacesServlet - 1 - + + In order for JSF to bootstrap correctly, the + FacesServlet must be configured in web.xml as it + normally would even though you generally will not need to route requests + through it at all when using JSF with Spring Web Flow. + + +<!-- Just here so the JSF implementation can initialize, *not* used at runtime --> +<servlet> + <servlet-name>Faces Servlet</servlet-name> + <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> + <load-on-startup>1</load-on-startup> +</servlet> - - - Faces Servlet - *.faces -]]> +<!-- Just here so the JSF implementation can initialize --> +<servlet-mapping> + <servlet-name>Faces Servlet</servlet-name> + <url-pattern>*.faces</url-pattern> +</servlet-mapping> - - When using the JSF 1.2 Spring Faces components, you also need to configure a servlet for serving - CSS and JavaScript resources. This servlet must be mapped - to /resources/* in order for the URL's rendered by the components to function correctly. - - - Note that while the ResourceServlet is deprected in favor of the Spring 3 resources - element, it is still required for use with JSF 1.2 Spring Faces components. - - - - Resource Servlet - org.springframework.js.resource.ResourceServlet - 0 - + + The use of Facelets instead of JSP typically requires this in + web.xml: + + +!-- Use JSF view templates saved as *.xhtml, for use with Facelets --> +<context-param> + <param-name>javax.faces.DEFAULT_SUFFIX</param-name> + <param-value>.xhtml</param-value> +</context-param> + + + + Configuring web.xml in JSF 1.2 + + When using the JSF 1.2 Spring Faces component library, you also + need to configure a servlet for serving CSS and JavaScript resources. + This servlet must be mapped to /resources/* in order for the URL's + rendered by the components to function correctly. + + +<!-- Serves static resource content from .jar files such as spring-faces.jar --> +<servlet> + <servlet-name>Resource Servlet</servlet-name> + <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class> + <load-on-startup>0</load-on-startup> +</servlet> - - - Resource Servlet - /resources/* -]]> +<!-- Map all /resources requests to the Resource Servlet for handling --> +<servlet-mapping> + <servlet-name>Resource Servlet</servlet-name> + <url-pattern>/resources/*</url-pattern> +</servlet-mapping> - - The Spring Faces components require the use of Facelets instead of JSP, so the typical Facelets - configuration must be added as well when using these components. - - - - javax.faces.DEFAULT_SUFFIX - .xhtml -]]> - - - For optimal page-loading performance use the Spring Faces components - includeStyles and includeScripts (JSF 1.2 only). - These components will eagerly load the necessary - CSS stylesheets and JavaScript files at the position they are placed in your JSF view template. In accordance - with the recommendations of the Yahoo Performance Guildlines, these two tags should be placed in the head - section of any page that uses the Spring Faces components. For example: - - -For optimal page-loading performance use the Spring Faces + components includeStyles and includeScripts. + These components will eagerly load the necessary CSS stylesheets and + JavaScript files at the position they are placed in your JSF view + template. In accordance with the recommendations of the Yahoo + Performance Guildlines, these two tags should be placed in the + head section of any page that uses the Spring Faces + components. For example: + + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jstl/core" xmlns:sf="http://www.springframework.org/tags/faces" - contentType="text/html" encoding="UTF-8"> - - - - Hotel Booking Sample Application + contentType="text/html" encoding="UTF-8"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>Hotel Booking Sample Application</title> - - + <sf:includeStyles /> + <sf:includeScripts /> - - + <ui:insert name="headIncludes"/> +</head> ... - -]]> - - - This shows the opening of a typical Facelets XHTML layout template that uses these components to force the loading of - the needed CSS and JavaScript resources at the ideal position. - - - The includeStyles component includes the necessary resources for the Dojo widget theme. By default, it includes - the resources for the "tundra" theme. An alternate theme may be selected by setting the optional "theme" and "themePath" attributes - on the includeStyles component. For example: - - -]]> - - - will try to load a CSS stylesheet at "/styles/foobar/foobar.css" using the Spring JavaScript ResourceServlet. - - - - Configuring Web Flow for use with JSF - - This section explains how to configure Web Flow with JSF. - The next section provides more details specific to using Web Flow with JSF 2. - The following is sample configuration for Web Flow and JSF: - - - + + This shows the opening of a typical Facelets XHTML layout template + that uses these components to force the loading of the needed CSS and + JavaScript resources at the ideal position. + + The includeStyles component includes the necessary + resources for the Dojo widget theme. By default, it includes the + resources for the "tundra" theme. An alternate theme may be selected by + setting the optional "theme" and "themePath" attributes on the + includeStyles component. For example: + + +<sf:includeStyles themePath="/styles/" theme="foobar"/> + + + + will try to load a CSS stylesheet at "/styles/foobar/foobar.css" + using the Spring JavaScript ResourceServlet. + + + + + Configuring Web Flow for use with JSF + + This section explains how to configure Web Flow with JSF. The next + section provides more details specific to using Web Flow with JSF 2. The + following is sample configuration for Web Flow and JSF: + + +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:webflow="http://www.springframework.org/schema/webflow-config" xmlns:faces="http://www.springframework.org/schema/faces" @@ -205,845 +246,1002 @@ http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd http://www.springframework.org/schema/faces - http://www.springframework.org/schema/faces/spring-faces-2.0.xsd"> + http://www.springframework.org/schema/faces/spring-faces-2.0.xsd"> - - - - - - + <!-- Executes flows: the central entry point into the Spring Web Flow system --> + <webflow:flow-executor id="flowExecutor"> + <webflow:flow-execution-listeners> + <webflow:listener ref="facesContextListener"/> + </webflow:flow-execution-listeners> + </webflow:flow-executor> - - - - + <!-- The registry of executable flow definitions --> + <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF"> + <webflow:flow-location-pattern value="**/*-flow.xml" /> + </webflow:flow-registry> - - + <!-- Configures the Spring Web Flow JSF integration --> + <faces:flow-builder-services id="flowBuilderServices" /> - - + <!-- A listener maintain one FacesContext instance per Web Flow request. --> + <bean id="facesContextListener" + class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" /> -]]> +</beans> - - The main points are the installation of a FlowFacesContextLifecycleListener that - manages a single FacesContext for the duration of Web Flow request and the - use of the flow-builder-services element from the faces custom - namespace to configure rendering for a JSF environment. - - - See the swf-booking-faces reference application in the distribution for a complete working example. - - - - Configuring Spring MVC for use with JSF 2 - - In a JSF 2 environment you'll also need this Spring MVC related configuration: - - -The main points are the installation of a + FlowFacesContextLifecycleListener that manages a single + FacesContext for the duration of Web Flow request and the use of the + flow-builder-services element from the faces + custom namespace to configure rendering for a JSF environment. + + See the swf-booking-faces reference application in the distribution + for a complete working example. + + + + Configuring Spring MVC for JSF 2 + + In a JSF 2 environment you'll also need this Spring MVC related + configuration: + + +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:faces="http://www.springframework.org/schema/faces" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/faces - http://www.springframework.org/schema/faces/spring-faces-2.0.xsd"> + http://www.springframework.org/schema/faces/spring-faces-2.0.xsd"> - + <faces:resources /> - - - + <bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter"> + <property name="flowExecutor" ref="flowExecutor" /> + </bean> -]]> +</beans> - - The resources custom namespace element delegates JSF 2 resource - requests to the JSF 2 resource API. The JsfFlowHandlerAdapter - is a replacement for the FlowHandlerAdapter normally used with - Web Flow. This adapter initializes itself with a JsfAjaxHandler instead - of the SpringJavaSciprtAjaxHandler previously used with Spring - Faces components. - - - - Configuring faces-config.xml - - If using JSF 1.2 you need to provide the below configuration in - faces-config.xml - in order to use Facelets. If you are using JSP and not using the Spring Faces components, you do - not need to add anything to your faces-config.xml - - - - - com.sun.facelets.FaceletViewHandler - -]]> + + The resources custom namespace element delegates JSF 2 + resource requests to the JSF 2 resource API. The + JsfFlowHandlerAdapter is a replacement for the + FlowHandlerAdapter normally used with Web Flow. This adapter + initializes itself with a JsfAjaxHandler instead of the + SpringJavaSciprtAjaxHandler previously used with Spring Faces + components. + + + + Configuring faces-config.xml + + In JSF 1.2 you need to provide the below configuration in + faces-config.xml in order to use Facelets. If you are using + JSP and not using the Spring Faces components, you do not need to add + anything to your faces-config.xml + + +<faces-config> + <application> + <!-- Enables Facelets --> + <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> + </application> +</faces-config> - - If using JSF 2.0 then your faces-config.xml should use the faces-config schema version 2.0. - Also you should remove the FaceletViewHandler shown above if it is present as Facelets are now the default rendering technology in JSF 2. - - -In JSF 2.0 your faces-config.xml should use the faces-config schema + version 2.0. Also you should remove the FaceletViewHandler shown above (if + it is present) as Facelets are now the default rendering technology in JSF + 2. + + +<?xml version='1.0' encoding='UTF-8'?> +<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" - version="2.0"> + version="2.0"> - - -]]> +</faces-config> - - - Replacing the JSF Managed Bean Facility - - When JSF with Spring Web Flow you can completely replace the JSF managed bean facility with a combination of - Web Flow managed variables and Spring managed beans. It gives you a good deal more control over the lifecycle of - your managed objects with well-defined hooks for initialization and execution of your domain model. - Additionally, since you are presumably already using Spring for your business layer, it reduces the - conceptual overhead of having to maintain two different managed bean models. - - - In doing pure JSF development, you will quickly find that request scope is not long-lived enough for storing - conversational model objects that drive complex event-driven views. In JSF 1.2 the only available option is to begin - putting things into session scope, with the extra burden of needing to clean the objects up before - progressing to another view or functional area of the application. What is really needed is a managed scope - that is somewhere between request and session scope. - - - JSF 2 provides flash and view scopes that can be accessed programmatically via UIViewRoot.getViewMap(). - Spring Web Flow provides access to flash, view, flow, and conversation scopes. - These scopes are seamlessly integrated through JSF variable resolvers and work the same in JSF 1.2 and in JSF 2.0 applications. - - - Using Flow Variables - - The easiest and most natural way to declare and manage the model is through the use of - flow variables. - You can declare these variables at the beginning of the flow: - - ]]> + + + + Replacing the JSF Managed Bean Facility + + When using JSF with Spring Web Flow you can completely replace the + JSF managed bean facility with a combination of Web Flow managed variables + and Spring managed beans. It gives you a good deal more control over the + lifecycle of your managed objects with well-defined hooks for + initialization and execution of your domain model. Additionally, since you + are presumably already using Spring for your business layer, it reduces + the conceptual overhead of having to maintain two different managed bean + models. + + In doing pure JSF development, you will quickly find that request + scope is not long-lived enough for storing conversational model objects + that drive complex event-driven views. In JSF 1.2 the only available + option is to begin putting things into session scope, with the extra + burden of needing to clean the objects up before progressing to another + view or functional area of the application. What is really needed is a + managed scope that is somewhere between request and session scope. JSF 2 + provides flash and view scopes that can be accessed programmatically via + UIViewRoot.getViewMap(). Spring Web Flow provides access to flash, view, + flow, and conversation scopes. These scopes are seamlessly integrated + through JSF variable resolvers and work the same in JSF 1.2 and in JSF 2.0 + applications. + + + Using Flow Variables + + The easiest and most natural way to declare and manage the model + is through the use of flow + variables. You can declare these variables at the beginning of + the flow: + + +<var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/> - and then reference this variable in one of the flow's JSF view templates through EL: - ]]> + + and then reference this variable in one of the flow's JSF view + templates through EL: + + +<h:inputText id="searchString" value="#{searchCriteria.searchString}"/> - - Note that you do not need to prefix the variable with its scope when referencing it from the template - (though you can do so if you need to be more specific). As with standard JSF beans, all available scopes - will be searched for a matching variable, so you could change the scope of the variable in your flow - definition without having to modify the EL expressions that reference it. - - - You can also define view instance variables that are scoped to the current view and get cleaned up - automatically upon transitioning to another view. This is quite useful with JSF as views are often - constructed to handle multiple in-page events across many requests before transitioning to another view. - - - To define a view instance variable, you can use the - var - element inside a - view-state - definition: - - - -]]> + + Note that you do not need to prefix the variable with its scope + when referencing it from the template (though you can do so if you need + to be more specific). As with standard JSF beans, all available scopes + will be searched for a matching variable, so you could change the scope + of the variable in your flow definition without having to modify the EL + expressions that reference it. + + You can also define view instance variables that are scoped to the + current view and get cleaned up automatically upon transitioning to + another view. This is quite useful with JSF as views are often + constructed to handle multiple in-page events across many requests + before transitioning to another view. + + To define a view instance variable, you can use the + var element inside a view-state + definition: + + +<view-state id="enterSearchCriteria"> + <var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/> +</view-state> - - - Using Scoped Spring Beans - - Though defining autowired flow instance variables provides nice modularization and readability, - occasions may arise where you want to utilize the other capabilities of the Spring container such as - AOP. In these cases, you can define a bean in your Spring ApplicationContext and give it a specific web - flow scope: - - ]]> + + + + Using Scoped Spring Beans + + Though defining autowired flow instance variables provides nice + modularization and readability, occasions may arise where you want to + utilize the other capabilities of the Spring container such as AOP. In + these cases, you can define a bean in your Spring ApplicationContext and + give it a specific web flow scope: + + +<bean id="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria" scope="flow"/> - - The major difference with this approach is that the bean will not be fully initialized until it is first - accessed via an EL expression. This sort of lazy instantiation via EL is quite similar to how JSF - managed beans are typically allocated. - - - - Manipulating The Model - - The need to initialize the model before view rendering (such as by loading persistent entities from a - database) is quite common, but JSF by itself does not provide any convenient hooks for such - initialization. The flow definition language provides a natural facility for this through its - Actions - . Spring Web Flow provides some extra conveniences for converting the outcome of an action into a - JSF-specific data structure. For example: - - - -]]> + + The major difference with this approach is that the bean will not + be fully initialized until it is first accessed via an EL expression. + This sort of lazy instantiation via EL is quite similar to how JSF + managed beans are typically allocated. + + + + Manipulating The Model + + The need to initialize the model before view rendering (such as by + loading persistent entities from a database) is quite common, but JSF by + itself does not provide any convenient hooks for such initialization. + The flow definition language provides a natural facility for this + through its Actions . Spring Web + Flow provides some extra conveniences for converting the outcome of an + action into a JSF-specific data structure. For example: + + +<on-render> + <evaluate expression="bookingService.findBookings(currentUser.name)" + result="viewScope.bookings" result-type="dataModel" /> +</on-render> - - This will take the result of the - bookingService.findBookings - method an wrap it in a custom JSF DataModel so that the list can be used in a standard JSF DataTable - component: - - 0}"> - - Name + + This will take the result of the + bookingService.findBookings method an wrap it in a custom + JSF DataModel so that the list can be used in a standard JSF DataTable + component: + + +<h:dataTable id="bookings" styleClass="summary" value="#{bookings}" var="booking" + rendered="#{bookings.rowCount > 0}"> + <h:column> + <f:facet name="header">Name</f:facet> #{booking.hotel.name} - - - Confirmation number + </h:column> + <h:column> + <f:facet name="header">Confirmation number</f:facet> #{booking.id} - - - Action - - -]]> + </h:column> + <h:column> + <f:facet name="header">Action</f:facet> + <h:commandLink id="cancel" value="Cancel" action="cancelBooking" /> + </h:column> +</h:dataTable> - - - Data Model Implementations - - In the example above result-type="dataModel" results in the wrapping of List<Booking> with custom DataModel type. - The custom DataModel provides extra conveniences such as being serializable for storage beyond - request scope as well as access to the currently selected row in EL expressions. For example, on postback from - a view where the action event was fired by a component within a DataTable, you can take action on the - selected row's model instance: - - - -]]> + + + + Data Model Implementations + + In the example above result-type="dataModel" results in the + wrapping of List<Booking> with custom + DataModel type. The custom + DataModel provides extra conveniences such as + being serializable for storage beyond request scope as well as access to + the currently selected row in EL expressions. For example, on postback + from a view where the action event was fired by a component within a + DataTable, you can take action on the selected row's model + instance: + + +<transition on="cancelBooking"> + <evaluate expression="bookingService.cancelBooking(bookings.selectedRow)" /> +</transition> - - Spring Web Flow provides two custom DataModel types: OneSelectionTrackingListDataModel and ManySelectionTrackingListDataModel. - As the names indicate they keep track of one or multiple selected rows. - This is done with the help of a SelectionTrackingActionListener listener, which responds to JSF action events and invokes the appopriate methods on the SelectinAware data models to record the currently clicked row. - - - To understand how this is configured, keep in mind the FacesConversionService registers a DataModelConverter against the alias "dataModel" on startup. - When result-type="dataModel" is used in a flow definition it causes the DataModelConverter to be used. - The converter then wraps the given List with an instance of OneSelectionTrackingListDataModel. - To use the ManySelectionTrackingListDataModel you will need to register your own custom converter. - - - - - Handling JSF Events With Spring Web Flow - - Spring Web Flow allows you to handle JSF action events in a decoupled way, requiring no direct dependencies - in your Java code on JSF API's. In fact, these events can often be handled completely in the flow definiton - language without requiring any custom Java action code at all. This allows for a more agile development - process since the artifacts being manipulated in wiring up events (JSF view templates and SWF flow - definitions) are instantly refreshable without requiring a build and re-deploy of the whole application. - - - Handling JSF In-page Action Events - - A simple but common case in JSF is the need to signal an event that causes manipulation of the model in - some way and then redisplays the same view to reflect the changed state of the model. The flow - definition language has special support for this in the - transition - element. - - - A good example of this is a table of paged list results. Suppose you want to be able to load and display - only a portion of a large result list, and allow the user to page through the results. The initial - view-state - definition to load and display the list would be: - - - - - -]]> + + Spring Web Flow provides two custom DataModel types: + OneSelectionTrackingListDataModel and + ManySelectionTrackingListDataModel. As the names + indicate they keep track of one or multiple selected rows. This is done + with the help of a + SelectionTrackingActionListener listener, which + responds to JSF action events and invokes the appopriate methods on the + SelectinAware data models to record the currently + clicked row. + + To understand how this is configured, keep in mind the + FacesConversionService registers a + DataModelConverter against the alias "dataModel" + on startup. When result-type="dataModel" is used in a flow definition it + causes the DataModelConverter to be used. The + converter then wraps the given List with an instance of + OneSelectionTrackingListDataModel. To use the + ManySelectionTrackingListDataModel you will need + to register your own custom converter. + + + + + Handling JSF Events With Spring Web Flow + + Spring Web Flow allows you to handle JSF action events in a + decoupled way, requiring no direct dependencies in your Java code on JSF + API's. In fact, these events can often be handled completely in the flow + definiton language without requiring any custom Java action code at all. + This allows for a more agile development process since the artifacts being + manipulated in wiring up events (JSF view templates and SWF flow + definitions) are instantly refreshable without requiring a build and + re-deploy of the whole application. + + + Handling JSF In-page Action Events + + A simple but common case in JSF is the need to signal an event + that causes manipulation of the model in some way and then redisplays + the same view to reflect the changed state of the model. The flow + definition language has special support for this in the + transition element. + + A good example of this is a table of paged list results. Suppose + you want to be able to load and display only a portion of a large result + list, and allow the user to page through the results. The initial + view-state definition to load and display the list would + be: + + +<view-state id="reviewHotels"> + <on-render> + <evaluate expression="bookingService.findHotels(searchCriteria)" + result="viewScope.hotels" result-type="dataModel" /> + </on-render> +</view-state> - - You construct a JSF DataTable that displays the current - hotels - list, and then place a "More Results" link below the table: - - ]]> + + You construct a JSF DataTable that displays the current + hotels list, and then place a "More Results" link below the + table: + + +<h:commandLink id="nextPageLink" value="More Results" action="next"/> - - This commandLink signals a "next" event from its action attribute. You can then handle the event by - adding to the - view-state - definition: - - - - - - - - -]]> + + This commandLink signals a "next" event from its action attribute. + You can then handle the event by adding to the view-state + definition: + + +<view-state id="reviewHotels"> + <on-render> + <evaluate expression="bookingService.findHotels(searchCriteria)" + result="viewScope.hotels" result-type="dataModel" /> + </on-render> + <transition on="next"> + <evaluate expression="searchCriteria.nextPage()" /> + </transition> +</view-state> - - Here you handle the "next" event by incrementing the page count on the searchCriteria instance. The - on-render - action is then called again with the updated criteria, which causes the next page of results to be - loaded into the DataModel. The same view is re-rendered since there was no - to - attribute on the - transition - element, and the changes in the model are reflected in the view. - - - - Handling JSF Action Events - - The next logical level beyond in-page events are events that require navigation to another view, with - some manipulation of the model along the way. Achieving this with pure JSF would require adding a - navigation rule to faces-config.xml and likely some intermediary Java code in a JSF managed bean (both - tasks requiring a re-deploy). With the flow defintion language, you can handle such a case concisely in - one place in a quite similar way to how in-page events are handled. - - - Continuing on with our use case of manipulating a paged list of results, suppose we want each row in the - displayed DataTable to contain a link to a detail page for that row instance. You can add a column to - the table containing the following - commandLink - component: - - ]]> + + Here you handle the "next" event by incrementing the page count on + the searchCriteria instance. The on-render action is then + called again with the updated criteria, which causes the next page of + results to be loaded into the DataModel. The same view is re-rendered + since there was no to attribute on the + transition element, and the changes in the model are + reflected in the view. + + + + Handling JSF Action Events + + The next logical level beyond in-page events are events that + require navigation to another view, with some manipulation of the model + along the way. Achieving this with pure JSF would require adding a + navigation rule to faces-config.xml and likely some intermediary Java + code in a JSF managed bean (both tasks requiring a re-deploy). With the + flow defintion language, you can handle such a case concisely in one + place in a quite similar way to how in-page events are handled. + + Continuing on with our use case of manipulating a paged list of + results, suppose we want each row in the displayed DataTable to contain + a link to a detail page for that row instance. You can add a column to + the table containing the following commandLink + component: + + +<h:commandLink id="viewHotelLink" value="View Hotel" action="select"/> - - This raises the "select" event which you can then handle by adding another - transition - element to the existing - view-state - : - - - - - - - - - - - -]]> + + This raises the "select" event which you can then handle by adding + another transition element to the existing + view-state : + + +<view-state id="reviewHotels"> + <on-render> + <evaluate expression="bookingService.findHotels(searchCriteria)" + result="viewScope.hotels" result-type="dataModel" /> + </on-render> + <transition on="next"> + <evaluate expression="searchCriteria.nextPage()" /> + </transition> + <transition on="select" to="reviewHotel"> + <set name="flowScope.hotel" value="hotels.selectedRow" /> + </transition> +</view-state> - - Here the "select" event is handled by pushing the currently selected hotel instance from the DataTable - into flow scope, so that it may be referenced by the "reviewHotel" - view-state - . - - - - Performing Model Validation - - JSF 1.2 provides useful facilities for validating input at field-level before changes are applied to the - model, but when you need to then perform more complex validation at the model-level after the updates - have been applied, you are generally left with having to add more custom code to your JSF action methods - in the managed bean. Validation of this sort is something that is generally a responsibility of the - domain model itself, but it is difficult to get any error messages propagated back to the view without - introducing an undesirable dependency on the JSF API in your domain layer. - - - With Web Flow, you can utilize the generic and low-level - MessageContext - in your business code and any messages added there will then be available to the - FacesContext - at render time. - - - For example, suppose you have a view where the user enters the necessary details to complete a hotel - booking, and you need to ensure the Check In and Check Out dates adhere to a given set of business - rules. You can invoke such model-level validation from a - transition - element: - - - - - -]]> + + Here the "select" event is handled by pushing the currently + selected hotel instance from the DataTable into flow scope, so that it + may be referenced by the "reviewHotel" view-state . + + + + Performing Model Validation + + JSF provides useful facilities for validating input at field-level + before changes are applied to the model, but when you need to then + perform more complex validation at the model-level after the updates + have been applied, you are generally left with having to add more custom + code to your JSF action methods in the managed bean. Validation of this + sort is something that is generally a responsibility of the domain model + itself, but it is difficult to get any error messages propagated back to + the view without introducing an undesirable dependency on the JSF API in + your domain layer. + + With Web Flow, you can utilize the generic and low-level + MessageContext in your business code and any messages added + there will then be available to the FacesContext at render + time. + + For example, suppose you have a view where the user enters the + necessary details to complete a hotel booking, and you need to ensure + the Check In and Check Out dates adhere to a given set of business + rules. You can invoke such model-level validation from a + transition element: + + +<view-state id="enterBookingDetails"> + <transition on="proceed" to="reviewBooking"> + <evaluate expression="booking.validateEnterBookingDetails(messageContext)" /> + </transition> +</view-state> - - Here the "proceed" event is handled by invoking a model-level validation method on the booking instance, - passing the generic - MessageContext - instance so that messages may be recorded. The messages can then be displayed along with any other JSF - messages with the - h:messages - component, - - - - Handling Ajax Events - - The Spring Faces - UICommand - components have the ability to do Ajax-based partial - view updates. These components degrade gracefully so that the flow will still be fully functional by - falling back to full page refreshes if a user with a less capable browser views the page. - - - Revisiting the earlier example with the paged table, you can change the "More Results" link to use an - Ajax request by replacing the standard - commandButton - with the Spring Faces component version (note that the Spring Faces command components use Ajax by default, but - they can alternately be forced to use a normal form submit by setting ajaxEnabled="false" on the - component): - - ]]> + + Here the "proceed" event is handled by invoking a model-level + validation method on the booking instance, passing the generic + MessageContext instance so that messages may be recorded. + The messages can then be displayed along with any other JSF messages + with the h:messages component, + + + + + + Handling Ajax Events In JSF 2.0 + + JSF 2 provides built-in support for sending Ajax requests and + performing partial processing and rendering on the server-side. You can + specify a list of id's for partial rendering through the <f:ajax> + facelets tag. + + In Spring Web Flow you also have the option to specify the ids to + use for partial rendering on the server side with the render + action: + + +<view-state id="reviewHotels"> + <on-render> + <evaluate expression="bookingService.findHotels(searchCriteria)" + result="viewScope.hotels" result-type="dataModel" /> + </on-render> + <transition on="next"> + <evaluate expression="searchCriteria.nextPage()" /> + <render fragments="hotels:searchResultsFragment" /> + </transition> +</view-state> + + + + + Handling Ajax Events In JSF 1.2 + + For JSF 1.2 the Spring Faces UICommand components + have the ability to do Ajax-based partial view updates. These components + degrade gracefully so that the flow will still be fully functional by + falling back to full page refreshes if a user with a less capable + browser views the page. + + Revisiting the earlier example with the paged table, you can + change the "More Results" link to use an Ajax request by replacing the + standard commandButton with the Spring Faces component + version (note that the Spring Faces command components use Ajax by + default, but they can alternately be forced to use a normal form submit + by setting ajaxEnabled="false" on the component): + + +<sf:commandLink id="nextPageLink" value="More Results" action="next" /> - - This event is handled just as in the non-Ajax case with the - transition - element, but now you will add a special - render - action that specifies which portions of the component tree need to be re-rendered: - - - - - - - - - -]]> + + This event is handled just as in the non-Ajax case with the + transition element, but now you will add a special + render action that specifies which portions of the + component tree need to be re-rendered: + + +<view-state id="reviewHotels"> + <on-render> + <evaluate expression="bookingService.findHotels(searchCriteria)" + result="viewScope.hotels" result-type="dataModel" /> + </on-render> + <transition on="next"> + <evaluate expression="searchCriteria.nextPage()" /> + <render fragments="hotels:searchResultsFragment" /> + </transition> +</view-state> - - The - fragments="hotels:searchResultsFragment" - is an instruction that will be interpreted at render time, such that only the component with the JSF - clientId "hotels:searchResultsFragment" will be rendered and returned to the client. This fragment will - then be automatically replaced in the page. The - fragments - attribute can be a comma-delimited list of ids, with each id representing the root node of a subtree - (meaning the root node and all of its children) to be rendered. If the "next" event is fired in a - non-Ajax request (i.e., if JavaScript is disabled on the client), the - render - action will be ignored and the full page will be rendered as normal. - - - In addition to the Spring Faces - commandLink - component, there is a corresponding - commandButton - component with the same functionality. There is also a special - ajaxEvent - component that will raise a JSF action even in response to any client-side DOM event. See the Spring - Faces tag library docs for full details. - - - An additional built-in feature when using the Spring Faces Ajax-enabled components is the ability to have the - response rendered inside a rich modal popup widget by setting - popup="true" - on a - view-state - . - - - - - - - - -]]> + + The fragments="hotels:searchResultsFragment" is an + instruction that will be interpreted at render time, such that only the + component with the JSF clientId "hotels:searchResultsFragment" will be + rendered and returned to the client. This fragment will then be + automatically replaced in the page. The fragments attribute + can be a comma-delimited list of ids, with each id representing the root + node of a subtree (meaning the root node and all of its children) to be + rendered. If the "next" event is fired in a non-Ajax request (i.e., if + JavaScript is disabled on the client), the render action + will be ignored and the full page will be rendered as normal. + + In addition to the Spring Faces commandLink + component, there is a corresponding commandButton component + with the same functionality. There is also a special + ajaxEvent component that will raise a JSF action even in + response to any client-side DOM event. See the Spring Faces tag library + docs for full details. + + An additional built-in feature when using the Spring Faces + Ajax-enabled components is the ability to have the response rendered + inside a rich modal popup widget by setting popup="true" on + a view-state . + + +<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true"> + <on-entry> + <render fragments="hotelSearchFragment" /> + </on-entry> + <transition on="search" to="reviewHotels"> + <evaluate expression="searchCriteria.resetPage()"/> + </transition> +</view-state> - - If the "changeSearchCriteria" - view-state - is reached as the result of an Ajax-request, the result will be rendered into a rich popup. If - JavaScript is unavailable, the request will be processed with a full browser refresh, and the - "changeSearchCriteria" view will be rendered as normal. - - - - - Using the Spring Security Facelets Tag Library - - To use the library you'll need to create a .taglib.xml file and register it in web.xml. - Unfortunately Spring Web Flow cannot easily do this automatically without causing issues for - either JSF 2 or JSF 1.2 users. In a future release we will consider splitting the security tag - library into a separate artifact with JSF 1.2 and 2.0 versions to make the library easier to add. - - - Note: all instructions you will see in this section assume you already know how - to configure Spring Security itself. - - - For JSF 2 save the following as /WEB-INF/springsecurity.taglib.xml: - - -If the "changeSearchCriteria" view-state is reached + as the result of an Ajax-request, the result will be rendered into a + rich popup. If JavaScript is unavailable, the request will be processed + with a full browser refresh, and the "changeSearchCriteria" view will be + rendered as normal. + + + + + Embedding a Flow On a Page + + By default when a flow enters a view state, it executes a + client-side redirect before rendering the view. This approach is known as + POST-REDIRECT-GET. It has the advantage of separating the form processing + for one view from the rendering of the next view. As a result the browser + Back and Refresh buttons work seamlessly without causing any browser + warnings. + + Normally the client-side redirect is transparent from a user's + perspective. However, there are situations where POST-REDIRECT-GET may not + bring the same benefits. For example sometimes it may be useful to embed + a flow on a page and drive it via Ajax requests refreshing only the area + of the page where the flow is rendered. Not only is it unnecessary to use + client-side redirects in this case, it is also not the desired behavior + with regards to keeping the surrounding content of the page intact. + + To indicate a flow should execute in "page embedded" mode all + you need to do is pass an extra flow input attribute called "mode" + with a value of "embedded". Below is an example of a top-level + container flow invoking a sub-flow in an embedded mode: + + +<subflow-state id="bookHotel" subflow="booking"> + <input name="mode" value="'embedded'"/> +</subflow-state> + + + When launched in "page embedded" mode the sub-flow will not issue + flow execution redirects during Ajax requests. + + If you'd like to see examples of an embedded flow please refer to + the webflow-primefaces-showcase project. You can check out + the source code locally, build it as you would a Maven project, and import + it into Eclipse: + + cd some-directory +svn co https://src.springframework.org/svn/spring-samples/webflow-primefaces-showcase +cd webflow-primefaces-showcase +mvn package +# import into Eclipse + + The specific example you need to look at is under the "Advanced Ajax" + tab and is called "Top Flow with Embedded Sub-Flow". + + + + + Redirect In Same State + + + By default Web Flow does a client-side redirect even it it remains in the same view state as long as the current request is not an Ajax request. + This is quite useful after form validation failures for example. + If the user hits Refresh or Back they won't see any browser warnings. + They would if the Web Flow didn't do a redirect. + + + This can lead to a problem specific to JSF 2 environments where JSF components in Sun Mojarra cache the FacesContext assuming the same instance is available throughout the JSF lifecycle. + In Web Flow however the render phase is temporarily put on hold and a client-side redirect executed. + + + The default behavior of Web Flow is desirable and it is unlikely JSF 2 applications will experience issue. + This is because Ajax is often enabled the default in JSF 2 component libraries and Web Flow does not redirect during Ajax requests. + However if you experience this issue you can disable client-side redirects within the same view as follows: + +<webflow:flow-executor id="flowExecutor"> + <webflow:flow-execution-attributes> + <webflow:redirect-in-same-state value="false"/> + </webflow:flow-execution-attributes> +</webflow:flow-executor> + + + + + + Using the Spring Security Facelets Tag Library + + To use the library you'll need to create a .taglib.xml + file and register it in web.xml. + + For JSF 2 create the file + /WEB-INF/springsecurity.taglib.xml with the following + content: + + +<?xml version="1.0"?> +<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" - "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> - - http://www.springframework.org/security/tags - - authorize - org.springframework.faces.security.FaceletsAuthorizeTagHandler - - - areAllGranted - org.springframework.faces.security.FaceletsAuthorizeTagUtils - boolean areAllGranted(java.lang.String) - - - areAnyGranted - org.springframework.faces.security.FaceletsAuthorizeTagUtils - boolean areAnyGranted(java.lang.String) - - - areNotGranted - org.springframework.faces.security.FaceletsAuthorizeTagUtils - boolean areNotGranted(java.lang.String) - - - isAllowed - org.springframework.faces.security.FaceletsAuthorizeTagUtils - boolean isAllowed(java.lang.String, java.lang.String) - - -]]> - - For JSF 1.2 use the same content as shown above but replace FaceletsAuthorizeTagHandler with - Jsf12FaceletsAuthorizeTagHandler and FaceletsAuthorizeTagUtils wiht - Jsf12FaceletsAuthorizeTagUtils. - - - Register the above file in web.xml: - - - javax.faces.FACELETS_LIBRARIES - /WEB-INF/springsecurity.taglib.xml - -]]> - - Now you are ready to use the tag library in your views. - You can use the authorize tag to include nested content conditionally: - - - + + For JSF 1.2 also create the file + /WEB-INF/springsecurity.taglib.xml but with the following + content instead: + + +<?xml version="1.0"?> +<!DOCTYPE facelet-taglib PUBLIC + "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> +<facelet-taglib> + <namespace>http://www.springframework.org/security/tags</namespace> + <tag> + <tag-name>authorize</tag-name> + <handler-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagHandler</handler-class> + </tag> + <function> + <function-name>areAllGranted</function-name> + <function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class> + <function-signature>boolean areAllGranted(java.lang.String)</function-signature> + </function> + <function> + <function-name>areAnyGranted</function-name> + <function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class> + <function-signature>boolean areAnyGranted(java.lang.String)</function-signature> + </function> + <function> + <function-name>areNotGranted</function-name> + <function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class> + <function-signature>boolean areNotGranted(java.lang.String)</function-signature> + </function> + <function> + <function-name>isAllowed</function-name> + <function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class> + <function-signature>boolean isAllowed(java.lang.String, java.lang.String)</function-signature> + </function> +</facelet-taglib> + + + Next, register the above file taglib in web.xml: + + <context-param> + <param-name>javax.faces.FACELETS_LIBRARIES</param-name> + <param-value>/WEB-INF/springsecurity.taglib.xml</param-value> +</context-param> + + + Now you are ready to use the tag library in your views. You can use + the authorize tag to include nested content conditionally: + + <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" - xmlns:sec="http://www.springframework.org/security/tags"> + xmlns:sec="http://www.springframework.org/security/tags"> - + <sec:authorize ifAllGranted="ROLE_FOO, ROLE_BAR"> Lorem ipsum dolor sit amet - + </sec:authorize> - + <sec:authorize ifNotGranted="ROLE_FOO, ROLE_BAR"> Lorem ipsum dolor sit amet - + </sec:authorize> - + <sec:authorize ifAnyGranted="ROLE_FOO, ROLE_BAR"> Lorem ipsum dolor sit amet - + </sec:authorize> - -]]> +</ui:composition> + - - You can also use one of several EL functions in the rendered or other - attribute of any JSF component: - + You can also use one of several EL functions in the rendered or + other attribute of any JSF component: - -<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" - xmlns:sec="http://www.springframework.org/security/tags"> + xmlns:sec="http://www.springframework.org/security/tags"> - - + <!-- Rendered only if user has all of the listed roles --> + <h:outputText value="Lorem ipsum dolor sit amet" rendered="#{sec:areAllGranted('ROLE_FOO, ROLE_BAR')}"/> - - + <!-- Rendered only if user does not have any of the listed roles --> + <h:outputText value="Lorem ipsum dolor sit amet" rendered="#{sec:areNotGranted('ROLE_FOO, ROLE_BAR')}"/> - - + <!-- Rendered only if user has any of the listed roles --> + <h:outputText value="Lorem ipsum dolor sit amet" rendered="#{sec:areAnyGranted('ROLE_FOO, ROLE_BAR')}"/> - - + <!-- Rendered only if user has access to given HTTP method/URL as defined in Spring Security configuration --> + <h:outputText value="Lorem ipsum dolor sit amet" rendered="#{sec:isAllowed('/secured/foo', 'POST')}"/> - -]]> +</ui:composition> + + - - - Enhancing The User Experience With Rich Web Forms - - JSF and Web Flow combine to provide an extensive server-side validation model for your web application, but - excessive roundtrips to the server to execute this validation and return error messages can be a tedious - experience for your users. The Spring Faces component library provides a number of client-side rich validation controls that can - enhance the user experience by applying simple validations that give immediate feedback. Some simple - examples are illustrated below. See the Spring Faces taglib docs for a complete tag reference. - - - Validating a Text Field - - Simple client-side text validation can be applied with the - clientTextValidator - component: - - - -]]> - - - This will apply client-side required validation to the child - inputText - component, giving the user a clear indicator if the field is left blank. - - - - Validating a Numeric Field - - Simple client-side numeric validation can be applied with the - clientNumberValidator - component: - - - -]]> - - - This will apply client-side validation to the child - inputText - component, giving the user a clear indicator if the field is left blank, is not numeric, or does not - match the given regular expression. - - - - Validating a Date Field - - Simple client-side date validation with a rich calendar popup can be applied with the - clientDateValidator - component: - - - - - -]]> - - - This will apply client-side validation to the child - inputText - component, giving the user a clear indicator if the field is left blank or is not a valid date. - - - - Preventing an Invalid Form Submission - - The - validateAllOnClick - component can be used to intercept the "onclick" event of a child component and suppress the event if - all client-side validations do not pass. - - -   -]]> - - - This will prevent the form from being submitted when the user clicks the "proceed" button if the form is - invalid. When the validations are executed, the user is given clear and immediate indicators of the - problems that need to be corrected. - - - - - Third-Party Component Library Integration - - The Spring Web Flow JSF integration strives to be compatible with any third-party JSF component library. By honoring all of the - standard semantics of the JSF specification within the SWF-driven JSF lifecycle, third-party libraries in - general should "just work". The main thing to remember is that configuration in web.xml will change slightly - since Web Flow requests are not routed through the standard FacesServlet. Typically, anything that is - traditionally mapped to the FacesServlet should be mapped to the Spring DispatcherServlet instead. (You can - also map to both if for example you are migrating a legacy JSF application page-by-page.) In some cases, a - deeper level of integration can be achieved by configuring special flow services that are "aware" of a - particular component library, and these will be noted in the examples to follow. - - - Rich Faces Integration - - To use the Rich Faces component library with Spring Web Flow, the following filter configuration is needed - in web.xml (in addition to the other typical configuration already shown): - - - RichFaces Filter - richfaces - org.ajax4jsf.Filter - + + Enhancing The User Experience With Rich Web Forms in JSF 1.2 - - richfaces - Spring Web MVC Dispatcher Servlet - REQUEST - FORWARD - INCLUDE -]]> + JSF and Web Flow combine to provide an extensive server-side + validation model for your web application, but excessive roundtrips to the + server to execute this validation and return error messages can be a + tedious experience for your users. The Spring Faces component library + provides a number of client-side rich validation controls that can enhance + the user experience by applying simple validations that give immediate + feedback. Some simple examples are illustrated below. See the Spring Faces + taglib docs for a complete tag reference. + + + Validating a Text Field + + Simple client-side text validation can be applied with the + clientTextValidator component: + + +<sf:clientTextValidator required="true"> + <h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/> +</sf:clientTextValidator> - - For deeper integration (including the ability to have a view with combined use of the Spring Faces Ajax - components and Rich Faces Ajax components), configure the RichFacesAjaxHandler on your FlowController: - - - - - - -]]> + + This will apply client-side required validation to the child + inputText component, giving the user a clear indicator if + the field is left blank. + + + + Validating a Numeric Field + + Simple client-side numeric validation can be applied with the + clientNumberValidator component: + + +<sf:clientTextValidator required="true" regExp="[0-9]{16}" + invalidMessage="A 16-digit credit card number is required."> + <h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/> +</sf:clientTextValidator> - - RichFaces Ajax components can be used in conjunction with the - render - tag to render partial fragments on an Ajax request. Instead of embedding the ids of the components to be - re-rendered directly in the view template (as you traditionally do with Rich Faces), you can bind the - reRender - attribute of a RichFaces Ajax component to a special - flowRenderFragments - EL variable. For example, in your view template you can have a fragment that you would potentially like - to re-render in response to a particular event: - - - - - - - Name + + This will apply client-side validation to the child + inputText component, giving the user a clear indicator if + the field is left blank, is not numeric, or does not match the given + regular expression. + + + + Validating a Date Field + + Simple client-side date validation with a rich calendar popup can + be applied with the clientDateValidator component: + + +<sf:clientDateValidator required="true" > + <h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true"> + <f:convertDateTime pattern="yyyy-MM-dd" timeZone="EST"/> + </h:inputText> +</sf:clientDateValidator> + + + This will apply client-side validation to the child + inputText component, giving the user a clear indicator if + the field is left blank or is not a valid date. + + + + Preventing an Invalid Form Submission + + The validateAllOnClick component can be used to + intercept the "onclick" event of a child component and suppress the + event if all client-side validations do not pass. + + +<sf:validateAllOnClick> + <sf:commandButton id="proceed" action="proceed" processIds="*" value="Proceed"/>&#160; +</sf:validateAllOnClick> + + + This will prevent the form from being submitted when the user + clicks the "proceed" button if the form is invalid. When the validations + are executed, the user is given clear and immediate indicators of the + problems that need to be corrected. + + + + + Third-Party Component Library Integration + + The Spring Web Flow JSF integration strives to be compatible with + any third-party JSF component library. By honoring all of the standard + semantics of the JSF specification within the SWF-driven JSF lifecycle, + third-party libraries in general should "just work". The main thing to + remember is that configuration in web.xml will change slightly since Web + Flow requests are not routed through the standard FacesServlet. Typically, + anything that is traditionally mapped to the FacesServlet should be mapped + to the Spring DispatcherServlet instead. (You can also map to both if for + example you are migrating a legacy JSF application page-by-page.) In some + cases, a deeper level of integration can be achieved by configuring + special flow services that are "aware" of a particular component library, + and these will be noted in the examples to follow. + + + Rich Faces Integration (JSF 1.2) + + To use the Rich Faces component library with Spring Web Flow, the + following filter configuration is needed in web.xml (in addition to the + other typical configuration already shown): + + +<filter> + <display-name>RichFaces Filter</display-name> + <filter-name>richfaces</filter-name> + <filter-class>org.ajax4jsf.Filter</filter-class> +</filter> + +<filter-mapping> + <filter-name>richfaces</filter-name> + <servlet-name>Spring Web MVC Dispatcher Servlet</servlet-name> + <dispatcher>REQUEST</dispatcher> + <dispatcher>FORWARD</dispatcher> + <dispatcher>INCLUDE</dispatcher> +</filter-mapping> + + + For deeper integration (including the ability to have a view with + combined use of the Spring Faces Ajax components and Rich Faces Ajax + components), configure the RichFacesAjaxHandler on your + FlowController: + + +<bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController"> + <property name="flowExecutor" ref="flowExecutor" /> + <property name="ajaxHandler"> + <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/> + </property> +</bean> + + + RichFaces Ajax components can be used in conjunction with the + render tag to render partial fragments on an Ajax request. + Instead of embedding the ids of the components to be re-rendered + directly in the view template (as you traditionally do with Rich Faces), + you can bind the reRender attribute of a RichFaces Ajax + component to a special flowRenderFragments EL variable. For + example, in your view template you can have a fragment that you would + potentially like to re-render in response to a particular event: + + +<h:form id="hotels"> + <a4j:outputPanel id="searchResultsFragment"> + <h:outputText id="noHotelsText" value="No Hotels Found" rendered="#{hotels.rowCount == 0}"/> + <h:dataTable id="hotels" styleClass="summary" value="#{hotels}" var="hotel" rendered="#{hotels.rowCount > 0}"> + <h:column> + <f:facet name="header">Name</f:facet> #{hotel.name} - - - Address + </h:column> + <h:column> + <f:facet name="header">Address</f:facet> #{hotel.address} - - - -]]> + </h:column> + </h:dataTable> + </a4j:outputPanel> +</h:form> - - then a RichFaces Ajax - commandLink - to fire the event: - - ]]> - - - and then in your flow definition a - transition - to handle the event: - - - - -]]> - - - - Apache MyFaces Trinidad Integration - - The Apache MyFaces Trinidad library has been tested with the Spring Web Flow's JSF integration and proven to fit - in nicely. Deeper integration to allow the Trinidad components and Spring Faces components to play - well together has not yet been attempted, but Trinidad provides a pretty thorough solution on its own - when used in conjunction with the Spring Web Flow JSF integration. - - - NOTE: An AjaxHandler implementation for Trinidad is not currently provided out-of-the-box. - In order to fully integrate with Trinidad's PPR functionality, a custom implementation should be - provided. An community-provided partial example can be found here: SWF-1160 - - - Typical configuration when using Trinidad with Web Flow is as follows in web.xml (in addition what has already been shown): - - - javax.faces.STATE_SAVING_METHOD - server - - - + then a RichFaces Ajax commandLink to fire the + event: + + +<a4j:commandLink id="nextPageLink" value="More Results" action="next" reRender="#{flowRenderFragments}" /> + + + and then in your flow definition a transition to + handle the event: + + +<transition on="next"> + <evaluate expression="searchCriteria.nextPage()" /> + <render fragments="hotels:searchResultsFragment" /> +</transition> + + + + + Apache MyFaces Trinidad Integration (JSF 1.2) + + The Apache MyFaces Trinidad library has been tested with the + Spring Web Flow's JSF integration and proven to fit in nicely. Deeper + integration to allow the Trinidad components and Spring Faces components + to play well together has not yet been attempted, but Trinidad provides + a pretty thorough solution on its own when used in conjunction with the + Spring Web Flow JSF integration. + + NOTE: An AjaxHandler implementation for Trinidad is + not currently provided out-of-the-box. In order to fully integrate with + Trinidad's PPR functionality, a custom implementation should be + provided. An community-provided partial example can be found here: + SWF-1160 + + Typical configuration when using Trinidad with Web Flow is as + follows in web.xml (in addition what has already been shown): + + +<context-param> + <param-name>javax.faces.STATE_SAVING_METHOD</param-name> + <param-value>server</param-value> +</context-param> + +<context-param> + <param-name> org.apache.myfaces.trinidad.CHANGE_PERSISTENCE - - session - + </param-name> + <param-value>session</param-value> +</context-param> - - +<context-param> + <param-name> org.apache.myfaces.trinidad.ENABLE_QUIRKS_MODE - - false - + </param-name> + <param-value>false</param-value> +</context-param> - - Trinidad Filter - +<filter> + <filter-name>Trinidad Filter</filter-name> + <filter-class> org.apache.myfaces.trinidad.webapp.TrinidadFilter - - + </filter-class> +</filter> - - Trinidad Filter - Spring MVC Dispatcher Servlet - +<filter-mapping> + <filter-name>Trinidad Filter</filter-name> + <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> +</filter-mapping> - - Trinidad Resource Servlet - +<servlet> + <servlet-name>Trinidad Resource Servlet</servlet-name> + <servlet-class> org.apache.myfaces.trinidad.webapp.ResourceServlet - - + </servlet-class> +</servlet> + +<servlet-mapping> + <servlet-name>resources</servlet-name> + <url-pattern>/adf/*</url-pattern> +</servlet-mapping> - - resources - /adf/* - -]]> - - - \ No newline at end of file + + + diff --git a/spring-webflow-reference/src/spring-mvc.xml b/spring-webflow-reference/src/spring-mvc.xml index 4d5980f6..9e6ba81d 100644 --- a/spring-webflow-reference/src/spring-mvc.xml +++ b/spring-webflow-reference/src/spring-mvc.xml @@ -1,138 +1,163 @@ +"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> - Spring MVC Integration - - Introduction - - This chapter shows how to integrate Web Flow into a Spring MVC web application. - The booking-mvc sample application is a good reference for Spring MVC with Web Flow. - This application is a simplified travel site that allows users to search for and book hotel rooms. - - - - Configuring web.xml - - The first step to using Spring MVC is to configure the DispatcherServlet in web.xml. - You typically do this once per web application. - - - The example below maps all requests that begin with /spring/ to the DispatcherServlet. - An init-param is used to provide the contextConfigLocation. - This is the configuration file for the web application. - - - Spring MVC Dispatcher Servlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - /WEB-INF/web-application-config.xml - - + Spring MVC Integration + + + Introduction + + This chapter shows how to integrate Web Flow into a Spring MVC web + application. The booking-mvc sample application is a good + reference for Spring MVC with Web Flow. This application is a simplified + travel site that allows users to search for and book hotel rooms. + + + + Configuring web.xml + + The first step to using Spring MVC is to configure the + DispatcherServlet in web.xml. You typically do + this once per web application. + + The example below maps all requests that begin with + /spring/ to the DispatcherServlet. An init-param + is used to provide the contextConfigLocation. This is the + configuration file for the web application. + + +<servlet> + <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> + <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> + <init-param> + <param-name>contextConfigLocation</param-name> + <param-value>/WEB-INF/web-application-config.xml</param-value> + </init-param> +</servlet> - - Spring MVC Dispatcher Servlet - /spring/* -]]> - - - Dispatching to flows - - The DispatcherServlet maps requests for application resources to handlers. - A flow is one type of handler. - - - Registering the FlowHandlerAdapter - - The first step to dispatching requests to flows is to enable flow handling within Spring MVC. - To this, install the FlowHandlerAdapter: - - - - -]]> +<servlet-mapping> + <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> + <url-pattern>/spring/*</url-pattern> +</servlet-mapping> + + + + Dispatching to flows + + The DispatcherServlet maps requests for application + resources to handlers. A flow is one type of handler. + + + Registering the FlowHandlerAdapter + + The first step to dispatching requests to flows is to enable flow + handling within Spring MVC. To this, install the + FlowHandlerAdapter: + + +<!-- Enables FlowHandler URL mapping --> +<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> + <property name="flowExecutor" ref="flowExecutor" /> +</bean> - - - Defining flow mappings - - Once flow handling is enabled, the next step is to map specific application resources to your flows. - The simplest way to do this is to define a FlowHandlerMapping: - - - - - -]]> + + + + Defining flow mappings + + Once flow handling is enabled, the next step is to map specific + application resources to your flows. The simplest way to do this is to + define a FlowHandlerMapping: + + +<!-- Maps request paths to flows in the flowRegistry; + e.g. a path of /hotels/booking looks for a flow with id "hotels/booking" --> +<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"> + <property name="flowRegistry" ref="flowRegistry"/> + <property name="order" value="0"/> +</bean> - - Configuring this mapping allows the Dispatcher to map application resource paths to flows in a flow registry. - For example, accessing the resource path /hotels/booking would result in a registry query for the flow with id hotels/booking. - If a flow is found with that id, that flow will handle the request. - If no flow is found, the next handler mapping in the Dispatcher's ordered chain will be queried or a "noHandlerFound" response will be returned. - - - - Flow handling workflow - - When a valid flow mapping is found, the FlowHandlerAdapter figures out whether to - start a new execution of that flow or resume an existing execution based on information present the HTTP request. - There are a number of defaults related to starting and resuming flow executions the adapter employs: - - - - - HTTP request parameters are made available in the input map of all starting flow executions. - - - - - When a flow execution ends without sending a final response, the default handler will attempt - to start a new execution in the same request. - - - - - Unhandled exceptions are propagated to the Dispatcher unless the exception is a NoSuchFlowExecutionException. - The default handler will attempt to recover from a NoSuchFlowExecutionException by starting over a new execution. - - - - - Consult the API documentation for FlowHandlerAdapter for more information. - You may override these defaults by subclassing or by implementing your own FlowHandler, discussed in the next section. - - - - - Implementing custom FlowHandlers - - FlowHandler is the extension point that can be used to customize how flows are executed in a HTTP servlet environment. - A FlowHandler is used by the FlowHandlerAdapter and is responsible for: - - - - Returning the id of a flow definition to execute - - - Creating the input to pass new executions of that flow as they are started - - - Handling outcomes returned by executions of that flow as they end - - - Handling any exceptions thrown by executions of that flow as they occur - - - - These responsibilities are illustrated in the definition of the org.springframework.mvc.servlet.FlowHandler interface: - - + + Configuring this mapping allows the Dispatcher to map application + resource paths to flows in a flow registry. For example, accessing the + resource path /hotels/booking would result in a registry + query for the flow with id hotels/booking. If a flow is + found with that id, that flow will handle the request. If no flow is + found, the next handler mapping in the Dispatcher's ordered chain will + be queried or a "noHandlerFound" response will be returned. + + + + Flow handling workflow + + When a valid flow mapping is found, the + FlowHandlerAdapter figures out whether to start a new + execution of that flow or resume an existing execution based on + information present the HTTP request. There are a number of defaults + related to starting and resuming flow executions the adapter + employs: + + + + HTTP request parameters are made available in the input map of + all starting flow executions. + + + + When a flow execution ends without sending a final response, + the default handler will attempt to start a new execution in the + same request. + + + + Unhandled exceptions are propagated to the Dispatcher unless + the exception is a NoSuchFlowExecutionException. The default handler + will attempt to recover from a NoSuchFlowExecutionException by + starting over a new execution. + + + + Consult the API documentation for FlowHandlerAdapter + for more information. You may override these defaults by subclassing or + by implementing your own FlowHandler, discussed in the next + section. + + + + + Implementing custom FlowHandlers + + FlowHandler is the extension point that can be used to + customize how flows are executed in a HTTP servlet environment. A + FlowHandler is used by the FlowHandlerAdapter + and is responsible for: + + + + Returning the id of a flow definition to + execute + + + + Creating the input to pass new executions of that flow as they + are started + + + + Handling outcomes returned by executions of that flow as they + end + + + + Handling any exceptions thrown by executions of that flow as + they occur + + + + These responsibilities are illustrated in the definition of the + org.springframework.mvc.servlet.FlowHandler interface: + + public interface FlowHandler { public String getFlowId(); @@ -146,46 +171,56 @@ public interface FlowHandler { HttpServletRequest request, HttpServletResponse response); } - - To implement a FlowHandler, subclass AbstractFlowHandler. All these operations are optional, and if not implemented - the defaults will apply. You only need to override the methods that you need. Specifically: - - - - - Override getFlowId(HttpServletRequest) when the id of your flow cannot be directly derived from the HTTP request. - By default, the id of the flow to execute is derived from the pathInfo portion of the request URI. - For example, http://localhost/app/hotels/booking?hotelId=1 results in a flow id of hotels/booking by default. - - - - - Override createExecutionInputMap(HttpServletRequest) when you need fine-grained control over extracting - flow input parameters from the HttpServletRequest. By default, all request parameters are treated as flow input parameters. - - - - - Override handleExecutionOutcome when you need to handle specific flow execution outcomes in a custom manner. - The default behavior sends a redirect to the ended flow's URL to restart a new execution of the flow. - - - - - Override handleException when you need fine-grained control over unhandled flow exceptions. - The default behavior attempts to restart the flow when a client attempts to access an ended or expired flow execution. - Any other exception is rethrown to the Spring MVC ExceptionResolver infrastructure by default. - - - - - Example FlowHandler - - A common interaction pattern between Spring MVC And Web Flow is for a Flow to redirect to a @Controller when it ends. - FlowHandlers allow this to be done without coupling the flow definition itself with a specific controller URL. - An example FlowHandler that redirects to a Spring MVC Controller is shown below: - - To implement a FlowHandler, subclass + AbstractFlowHandler. All these operations are optional, and + if not implemented the defaults will apply. You only need to override the + methods that you need. Specifically: + + + + Override getFlowId(HttpServletRequest) when the id + of your flow cannot be directly derived from the HTTP request. By + default, the id of the flow to execute is derived from the pathInfo + portion of the request URI. For example, + http://localhost/app/hotels/booking?hotelId=1 results in + a flow id of hotels/booking by default. + + + + Override + createExecutionInputMap(HttpServletRequest) when you need + fine-grained control over extracting flow input parameters from the + HttpServletRequest. By default, all request parameters are treated as + flow input parameters. + + + + Override handleExecutionOutcome when you need to + handle specific flow execution outcomes in a custom manner. The + default behavior sends a redirect to the ended flow's URL to restart a + new execution of the flow. + + + + Override handleException when you need fine-grained + control over unhandled flow exceptions. The default behavior attempts + to restart the flow when a client attempts to access an ended or + expired flow execution. Any other exception is rethrown to the Spring + MVC ExceptionResolver infrastructure by default. + + + + + Example FlowHandler + + A common interaction pattern between Spring MVC And Web Flow is + for a Flow to redirect to a @Controller when it ends. FlowHandlers allow + this to be done without coupling the flow definition itself with a + specific controller URL. An example FlowHandler that redirects to a + Spring MVC Controller is shown below: + + public class BookingFlowHandler extends AbstractFlowHandler { public String handleExecutionOutcome(FlowExecutionOutcome outcome, HttpServletRequest request, HttpServletResponse response) { @@ -195,135 +230,244 @@ public class BookingFlowHandler extends AbstractFlowHandler { return "/hotels/index"; } } -}]]> +} - - Since this handler only needs to handle flow execution outcomes in a custom manner, nothing else is overridden. - The bookingConfirmed outcome will result in a redirect to show the new booking. - Any other outcome will redirect back to the hotels index page. - - - - Deploying a custom FlowHandler - - To install a custom FlowHandler, simply deploy it as a bean. - The bean name must match the id of the flow the handler should apply to. - - ]]> + + Since this handler only needs to handle flow execution outcomes in + a custom manner, nothing else is overridden. The + bookingConfirmed outcome will result in a redirect to show + the new booking. Any other outcome will redirect back to the hotels + index page. + + + + Deploying a custom FlowHandler + + To install a custom FlowHandler, simply deploy it as a bean. The + bean name must match the id of the flow the handler should apply + to. + + +<bean name="hotels/booking" class="org.springframework.webflow.samples.booking.BookingFlowHandler" /> - - With this configuration, accessing the resource /hotels/booking will launch the hotels/booking flow using the custom BookingFlowHandler. - When the booking flow ends, the FlowHandler will process the flow execution outcome and redirect to the appropriate controller. - - - - FlowHandler Redirects - - A FlowHandler handling a FlowExecutionOutcome or FlowException returns a String to indicate the resource to redirect to after handling. - In the previous example, the BookingFlowHandler redirects to the booking/show resource URI for bookingConfirmed outcomes, - and the hotels/index resource URI for all other outcomes. - - - By default, returned resource locations are relative to the current servlet mapping. - This allows for a flow handler to redirect to other Controllers in the application using relative paths. - In addition, explicit redirect prefixes are supported for cases where more control is needed. - - - The explicit redirect prefixes supported are: - - - servletRelative: - redirect to a resource relative to the current servlet - contextRelative: - redirect to a resource relative to the current web application context path - serverRelative: - redirect to a resource relative to the server root - http:// or https:// - redirect to a fully-qualified resource URI - - - These same redirect prefixes are also supported within a flow definition when using the externalRedirect: directive in - conjunction with a view-state or end-state; for example, view="externalRedirect:http://springframework.org" - - - - - View Resolution - - Web Flow 2 maps selected view identifiers to files located within the flow's working directory unless otherwise specified. - For existing Spring MVC + Web Flow applications, an external ViewResolver is likely already handling this mapping for you. - Therefore, to continue using that resolver and to avoid having to change how your existing flow views are packaged, configure Web Flow as follows: - - - - - + With this configuration, accessing the resource + /hotels/booking will launch the hotels/booking + flow using the custom BookingFlowHandler. When the booking flow ends, + the FlowHandler will process the flow execution outcome and redirect to + the appropriate controller. + - - -]]> + + FlowHandler Redirects + + A FlowHandler handling a FlowExecutionOutcome or FlowException + returns a String to indicate the resource to redirect to + after handling. In the previous example, the + BookingFlowHandler redirects to the + booking/show resource URI for bookingConfirmed + outcomes, and the hotels/index resource URI for all other + outcomes. + + By default, returned resource locations are relative to the + current servlet mapping. This allows for a flow handler to redirect to + other Controllers in the application using relative paths. In addition, + explicit redirect prefixes are supported for cases where more control is + needed. + + The explicit redirect prefixes supported are: + + + + servletRelative: - redirect to a resource + relative to the current servlet + + + + contextRelative: - redirect to a resource + relative to the current web application context path + + + + serverRelative: - redirect to a resource relative + to the server root + + + + http:// or https:// - redirect to a + fully-qualified resource URI + + + + These same redirect prefixes are also supported within a flow + definition when using the externalRedirect: directive in + conjunction with a view-state or end-state; for example, + view="externalRedirect:http://springframework.org" + + + + + View Resolution + + Web Flow 2 maps selected view identifiers to files located within + the flow's working directory unless otherwise specified. For existing + Spring MVC + Web Flow applications, an external ViewResolver + is likely already handling this mapping for you. Therefore, to continue + using that resolver and to avoid having to change how your existing flow + views are packaged, configure Web Flow as follows: + + +<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices"> + <webflow:location path="/WEB-INF/hotels/booking/booking.xml" /> +</webflow:flow-registry> + +<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"/> + +<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator"> + <property name="viewResolvers" ref="myExistingViewResolverToUseForFlows"/> +</bean> + + The MvcViewFactoryCreator is the factory that allows you to + configure how the Spring MVC view system is used inside Spring Web Flow. + Use it to configure existing ViewResolvers, as well as other services such + as a custom MessageCodesResolver. You may also enable data binding use + Spring MVC's native BeanWrapper by setting the + useSpringBinding flag to true. This is an alternative to + using OGNL or the Unified EL for view-to-model data binding. See the + JavaDoc API of this class for more information. + + + + Signaling an event from a View + + When a flow enters a view-state it pauses, redirects the user to its + execution URL, and waits for a user event to resume. Events are generally + signaled by activating buttons, links, or other user interface commands. + How events are decoded server-side is specific to the view technology in + use. This section shows how to trigger events from HTML-based views + generated by templating engines such as JSP, Velocity, or + Freemarker. + + + Using a named HTML button to signal an event + + The example below shows two buttons on the same form that signal + proceed and cancel events when clicked, + respectively. + + +<input type="submit" name="_eventId_proceed" value="Proceed" /> +<input type="submit" name="_eventId_cancel" value="Cancel" /> + + + When a button is pressed Web Flow finds a request parameter name + beginning with _eventId_ and treats the remaining substring + as the event id. So in this example, submitting + _eventId_proceed becomes proceed. This style + should be considered when there are several different events that can be + signaled from the same form. + + + + Using a hidden HTML form parameter to signal an event + + The example below shows a form that signals the + proceed event when submitted: + + +<input type="submit" value="Proceed" /> +<input type="hidden" name="_eventId" value="proceed" /> + + + Here, Web Flow simply detects the special _eventId + parameter and uses its value as the event id. This style should only be + considered when there is one event that can be signaled on the + form. + + + + Using a HTML link to signal an event + + The example below shows a link that signals the + cancel event when activated: + + +<a href="${flowExecutionUrl}&_eventId=cancel">Cancel</a> + + + Firing an event results in a HTTP request being sent back to the + server. On the server-side, the flow handles decoding the event from + within its current view-state. How this decoding process works is + specific to the view implementation. Recall a Spring MVC view + implementation simply looks for a request parameter named + _eventId. If no _eventId parameter is found, + the view will look for a parameter that starts with + _eventId_ and will use the remaining substring as the event + id. If neither cases exist, no flow event is triggered. + + + + + Embedding A Flow On A Page + + By default when a flow enters a view state, it executes a + client-side redirect before rendering the view. This approach is known as + POST-REDIRECT-GET. It has the advantage of separating the form processing + for one view from the rendering of the next view. As a result the browser + Back and Refresh buttons work seamlessly without causing any browser + warnings. + + Normally the client-side redirect is transparent from a user's + perspective. However, there are situations where POST-REDIRECT-GET may not + bring the same benefits. For example a flow may be embedded on a page and driven via + Ajax requests refreshing only the area of the page that belongs to the flow. + Not only is it unnecessary to use client-side redirects in this case, it + is also not the desired behavior with regards to keeping the surrounding + content of the page intact. + + The explains how to do + partial rendering during Ajax requests. The focus of this section is to + explain how to control flow execution redirect behavior during + Ajax requests. To indicate a flow should execute in "page embedded" mode all + you need to do is append an extra parameter when launching the + flow: + + /hotels/booking?mode=embedded + + When launched in "page embedded" mode a flow will not issue + flow execution redirects during Ajax requests. The mode=embedded parameter + only needs to be passed when launching the flow. Your only other concern is + to use Ajax requests and to render only the content required to update + the portion of the page displaying the flow. + + + Embedded Mode Vs Default Redirect Behavior - The MvcViewFactoryCreator is the factory that allows you to configure how the Spring MVC view system is used inside Spring Web Flow. - Use it to configure existing ViewResolvers, as well as other services such as a custom MessageCodesResolver. - You may also enable data binding use Spring MVC's native BeanWrapper by setting the useSpringBinding flag to true. - This is an alternative to using OGNL or the Unified EL for view-to-model data binding. - See the JavaDoc API of this class for more information. + By default Web Flow does a client-side redirect upon entering every view state. + However if you remain in the same view state -- for example a transition without a "to" attribute -- during an Ajax request there will not be a client-side redirect. + This behavior should be quite familiar to Spring Web Flow 2 users. + It is appropriate for a top-level flow that supports the browser back button while still taking advantage of Ajax and partial rendering for use cases where you remain in the same view such as form validation, paging trough search results, and others. + However transitions to a new view state are always followed with a client-side redirect. + That makes it impossible to embed a flow on a page or within a modal dialog and execute more than one view state without causing a full-page refresh. + Hence if your use case requires embedding a flow you can launch it in "embedded" mode. - - - Signaling an event from a View - - When a flow enters a view-state it pauses, redirects the user to its execution URL, and waits for a user event to resume. - Events are generally signaled by activating buttons, links, or other user interface commands. - How events are decoded server-side is specific to the view technology in use. - This section shows how to trigger events from HTML-based views generated by templating engines such as JSP, Velocity, or Freemarker. + + + + Embedded Flow Examples + If you'd like to see examples of a flow embedded on a page and within + a modal dialog please refer to the webflow-showcase project. You can check out + the source code locally, build it as you would a Maven project, and import + it into Eclipse: + + cd some-directory +svn co https://src.springframework.org/svn/spring-samples/webflow-showcase +cd webflow-showcase +mvn package +# import into Eclipse - - Using a named HTML button to signal an event - - The example below shows two buttons on the same form that signal proceed and cancel events when clicked, respectively. - - -]]> - - - When a button is pressed Web Flow finds a request parameter name beginning with _eventId_ and treats the remaining substring as the event id. - So in this example, submitting _eventId_proceed becomes proceed. - This style should be considered when there are several different events that can be signaled from the same form. - - - - Using a hidden HTML form parameter to signal an event - - The example below shows a form that signals the proceed event when submitted: - - -]]> - - - Here, Web Flow simply detects the special _eventId parameter and uses its value as the event id. - This style should only be considered when there is one event that can be signaled on the form. - - - - Using a HTML link to signal an event - - The example below shows a link that signals the cancel event when activated: - - Cancel]]> - - - Firing an event results in a HTTP request being sent back to the server. - On the server-side, the flow handles decoding the event from within its current view-state. - How this decoding process works is specific to the view implementation. - Recall a Spring MVC view implementation simply looks for a request parameter named _eventId. - If no _eventId parameter is found, the view will look for a parameter that - starts with _eventId_ and will use the remaining substring as the event id. - If neither cases exist, no flow event is triggered. - - - - \ No newline at end of file + + + + diff --git a/spring-webflow-reference/src/views.xml b/spring-webflow-reference/src/views.xml index 67df5b67..d1ac2360 100644 --- a/spring-webflow-reference/src/views.xml +++ b/spring-webflow-reference/src/views.xml @@ -448,8 +448,38 @@ public class ApplicationConversionServiceFactoryBean extends FormattingConversio Validating a model Model validation is driven by constraints specified against a model object. - Web Flow supports enforcing such constraints programatically. + Web Flow supports enforcing such constraints programatically as well as + declaratively with JSR-303 Bean Validation annotations. + + JSR-303 Bean Validation + + Web Flow provides built-in support for the JSR-303 Bean Validation API + building on equivalent support available in Spring MVC. + To enable JSR-303 validation configure the flow-builder-services with + Spring MVC's LocalValidatorFactoryBean: + + +<webflow:flow-registry flow-builder-services="flowBuilderServices" /> + +<webflow:flow-builder-services id="flowBuilderServices" validator="validator" /> + +<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> + + + + With the above in place, the configured validator will be applied to + all model attributes after data binding. + + + + Note that JSR-303 bean validation and validation by convention + (explained in the next section) are not mutually exclusive. + In other words Web Flow will apply all available validation + mechanisms. + + + Programmatic validation diff --git a/spring-webflow-reference/src/whatsnew.xml b/spring-webflow-reference/src/whatsnew.xml index b5752319..09fc7ab8 100644 --- a/spring-webflow-reference/src/whatsnew.xml +++ b/spring-webflow-reference/src/whatsnew.xml @@ -2,122 +2,206 @@ - What's New In Spring Web Flow 2.2.0 - - JSF 2 Support - - Comprehensive JSF 2 Support + What's New + + Spring Web Flow 2.3 + + Embedding A Flow On A Page - Building on 2.1, Spring Web Flow version 2.2 adds support for core JSF 2 features - The following features that were not supported in 2.1 are now available: - partial state saving, JSF 2 resource request, handling, and JSF 2 Ajax requests. - At this point support for JSF 2 is considered - comprehensive although not covering every JSF 2 feature -- - excluded are mostly features that overlap with the core value Web Flow provides - such as those relating to navigation and state management. - - - See for important configuration changes. - Note that partial state saving is only supported with Sun Mojarra 2.0.3 or later. - It is not yet supported with Apache MyFaces. This is due to the - fact MyFaces was not as easy to customize with regards to how component state is stored. - We will work with Apache MyFaces to provide this support. In the mean time you will need to use - the javax.faces.PARTIAL_STATE_SAVING context parameter in web.xml - to disable partial state saving with Apache MyFaces. + By default Web Flow does a client-side redirect upon entering every view state. + That makes it impossible to embed a flow on a page or within a modal dialog and execute more than one view state without causing a full-page refresh. + Web Flow now supports launching a flow in "embedded" mode. + In this mode a flow can transition to other view states without a client-side redirect during Ajax requests. + See and . - - Travel Sample With the PrimeFaces Components + + Support For JSR-303 Bean Validation - The main Spring Travel sample demonstrating Spring Web Flow and JSF support - is now built on JSF 2 and components from the PrimeFaces component library. - Please check out the booking-faces sample in the distribution. + Support for the JSR-303 Bean Validation API is now available building on equivalent support available in Spring MVC. + See for more details. + + + + Flow-Managed Persistence Context Propagation + + Starting with Web Flow 2.3 a flow managed PersistenceContext is automatically extended (propagated) to sub-flows assuming the subflow also has the feature enabled as well. + See . + + + + Portlet 2.0 Resource Requests + + Support for Portlet 2.0 resource requests has now been added enabling Ajax requests with partial rendering. + URLs for such requests can be prepared with the <portlet:resourceURL> tag in JSP pages. + Server-side processing is similar to a combined an action and a render requests but combined in a single request. + Unlike a render request, the response from a resource request includes content from the target portlet only. + + + + Custom ConversationManager + + The <flow-execution-repository> element now provides a conversation-manager attribute accepting a reference to a ConversationManager instance. + + + + Redirect In Same State + + By default Web Flow does a client-side redirect when remaining in the same view state as long as the current request is not an Ajax request. + This is useful after form validation failure. + Hitting Refresh or Back won't result in browser warnings. + Hence this behavior is usually desirable. + However a new flow execution attribute makes it possible to disable it and that may also be necessary in some cases specific to JSF 2 applications. + See . + + + + Samples + + The process for building the samples included with the distribution has been simplified. + Maven can be used to build all samples in one step. + Eclipse settings include source code references to simplify debugging. - Additional samples can be found at the Spring Web Flow - Prime Faces - - Showcase, an SVN repository within the - spring-samples - repository. Use these commands to check out and build: - -mkdir spring-samples +cd spring-samples +svn co https://src.springframework.org/svn/spring-samples/webflow-primefaces-showcase cd webflow-primefaces-showcase mvn package -]]> +# import into Eclipse + - - - - Spring Security Facelets Tag Library - - A new Spring Security tag library is available for use with with JSF 2.0 or with JSF 1.2 Facelets views. - It provides an <authorize> tag as well as several EL functions. - See for more details. - - - - Spring JavaScript Updates - - Deprecated ResourcesServlet - - Starting with Spring 3.0.4, the Spring Framework includes - a replacement for the ResourcesServlet. Please see - the Spring Framework documentation for details on the custom mvc namespace, - specifically the new - "resources" - element. - - - - Dojo 1.5 and dojox - - The bundled custom Dojo build is upgraded to version 1.5. It now includes dojox. - - - Note that applications are generally encouraged to prepare their own custom - Dojo build for optimized performance depending on what parts of Dojo are - commonly used together. For examples see the - scripts - used by Spring Web Flow to prepare its own custom Dojo build. - - - - Two Spring JS artifacts - - The spring-js artifact has been split in two -- the new artifact - (spring-js-resources) contains client side resource (.js, .css, etc.) while - the existing artifact (spring-js) contains server-side Java code only. - - - Applications preparing their own custom Dojo build have an option now to - avoid including spring-js-resources and put Spring.js and - Spring-Dojo.js directly under the root of their web application. - - - - Client resources moved into META-INF/web-resources - - Bundled client resources (.js, .css, etc.) - have been moved to META-INF/web-resources from their previous location - under META-INF. This change is transparent for applications but will result - in simpler and safer configuration when using the new resource handling - mechanism available in Spring 3.0.4. +mkdir spring-samples +cd spring-samples +svn co https://src.springframework.org/svn/spring-samples/webflow-showcase +cd webflow-showcase +mvn package +# import into Eclipse + - - JFS Portlet Support - - Portlet API 2.0 and JSF 1.2 support + + + Spring Web Flow 2.2 + + JSF 2 Support + + Comprehensive JSF 2 Support + + Building on 2.1, Spring Web Flow version 2.2 adds support for core JSF 2 features + The following features that were not supported in 2.1 are now available: + partial state saving, JSF 2 resource request, handling, and JSF 2 Ajax requests. + At this point support for JSF 2 is considered + comprehensive although not covering every JSF 2 feature -- + excluded are mostly features that overlap with the core value Web Flow provides + such as those relating to navigation and state management. + + + See for important configuration changes. + Note that partial state saving is only supported with Sun Mojarra 2.0.3 or later. + It is not yet supported with Apache MyFaces. This is due to the + fact MyFaces was not as easy to customize with regards to how component state is stored. + We will work with Apache MyFaces to provide this support. In the mean time you will need to use + the javax.faces.PARTIAL_STATE_SAVING context parameter in web.xml + to disable partial state saving with Apache MyFaces. + + + + Travel Sample With the PrimeFaces Components + + The main Spring Travel sample demonstrating Spring Web Flow and JSF support + is now built on JSF 2 and components from the PrimeFaces component library. + Please check out the booking-faces sample in the distribution. + + + Additional samples can be found at the Spring Web Flow - Prime Faces + + Showcase, an SVN repository within the + spring-samples + repository. Use these commands to check out and build: + + + + + + + Spring Security Facelets Tag Library - In previous versions of Spring Web Flow support for JSF Portlets relied on - a Portlet Bridge for JSF implementation and was considered experimental. - Spring Web Flow 2.2 adds support for JSF Portlets based on its own internal - Portlet integration targeting Portlet API 2.0 and JSF 1.2 environments. - See for more details. - The Spring Web Flow Travel JSF Portlets sample has been successfully - tested on the Apache Pluto portal container. + A new Spring Security tag library is available for use with with JSF 2.0 or with JSF 1.2 Facelets views. + It provides an <authorize> tag as well as several EL functions. + See for more details. + + Spring JavaScript Updates + + Deprecated ResourcesServlet + + Starting with Spring 3.0.4, the Spring Framework includes + a replacement for the ResourcesServlet. Please see + the Spring Framework documentation for details on the custom mvc namespace, + specifically the new + "resources" + element. + + + + Dojo 1.5 and dojox + + The bundled custom Dojo build is upgraded to version 1.5. It now includes dojox. + + + Note that applications are generally encouraged to prepare their own custom + Dojo build for optimized performance depending on what parts of Dojo are + commonly used together. For examples see the + scripts + used by Spring Web Flow to prepare its own custom Dojo build. + + + + Two Spring JS artifacts + + The spring-js artifact has been split in two -- the new artifact + (spring-js-resources) contains client side resource (.js, .css, etc.) while + the existing artifact (spring-js) contains server-side Java code only. + + + Applications preparing their own custom Dojo build have an option now to + avoid including spring-js-resources and put Spring.js and + Spring-Dojo.js directly under the root of their web application. + + + + Client resources moved into META-INF/web-resources + + Bundled client resources (.js, .css, etc.) + have been moved to META-INF/web-resources from their previous location + under META-INF. This change is transparent for applications but will result + in simpler and safer configuration when using the new resource handling + mechanism available in Spring 3.0.4. + + + + + JFS Portlet Support + + Portlet API 2.0 and JSF 1.2 support + + In previous versions of Spring Web Flow support for JSF Portlets relied on + a Portlet Bridge for JSF implementation and was considered experimental. + Spring Web Flow 2.2 adds support for JSF Portlets based on its own internal + Portlet integration targeting Portlet API 2.0 and JSF 1.2 environments. + See for more details. + The Spring Web Flow Travel JSF Portlets sample has been successfully + tested on the Apache Pluto portal container. + + + +