MVC using Spring Web Flow

  Written by The Jahia Team
   Estimated reading time:

1 Introduction

This document covers basic aspects of using Spring Web Flow for implementing advanced MVC-based content rendering, form processing, data binding and input validation in Digital Experience Manager.

 

2 How Is It Integrated in Digital Experience Manager

2.1 Rendering concepts

In this section we give as a reminder a quick overview of rendering concept in Digital Experience Manager.

2.1.1 Templates, areas and views

  • Each content node needs a template (full page view)
  • Template will define which elements to display and where to display them using areas
  • An area renders a content node using a view

2.1.2 Request rendering flow

The request rendering flow in Digital Experience Manager can be represented as follows:

2.1.3 Views

To render a content node Jahia needs a script file(s) called a view:

The example above shows how a same content item, a news entry in this case, can have multiple rendering views, depending on the context or needs.

2.1.4 View (script) types

The following view (script) types are supported in Digital Experience Manager:

  • JSP (javax.servlet.RequestDispatcher)
  • JSR-223: Groovy, Velocity, FreeMarker, etc. (javax.script.ScriptEngineManager)
  • Web Flow (javax.servlet.RequestDispatcher) dispatching to a dedicated controller (/flow/*)

The Web Flow type, which is acting as an intermediate layer, dispatches the request to a dedicated flow controller. The flow controller is responsible for handling flow initialization and executing “navigation” control and logic.

2.2 What Digital Experience Manager does for you

The Digital Experience Manager automatically:

  • detects and registers/unregisters flow definitions in modules;
  • does proper dispatching to controller, URL mappings, handler mapping, view resolution, message source resolution (i18n), etc.

It means the flow-based views are automatically detected in your module and registered during start of the module and automatically unregistered when the module is stopped.

Thus new views will be available for content rendering.

All the view resolution part (i.e. resolving a view script for a particular flow view state) and dispatching to it is also done transparently by the Digital Experience Manager without the need to introduce special URL and handler mappings.

2.3
What you need to use it

Here are the things that you have to include into your module:

  • a Spring bean definitions file (1)
  • a view (folder) of type “flow” (2)
  • a flow definition file – flow.xml (3)
  • flow view template files
  • action handlers
  • validation
  • i18n resources

2.3.1 Bean definitions file

The bean definitions file is mandatory to “tell” Digital Experience Manager that the module contains flow definitions to lookup and register. The bean definitions file doesn’t have to contain any beans, it just has to be present.

Nevertheless, if you are using resource bundles for internationalization you should include the following bean definition into that file:

<bean id="messageSource" class="org.jahia.utils.i18n.ModuleMessageSource"/>

And in case the JSR-303 “Bean Validation” annotations are used the following entry has to be present also:

<mvc:annotation-driven conversion-service="springTypeConversionService"/>

2.3.2 View of type “flow”

The view of type “flow” is actually represented by a folder, not a single file as in case of normal views.

The folder name by convention has the same format as usual view files, but also ends with “.flow” to indicate a particular view type. In the example above the folder is named job.showcase-apply.flow, which means it is a rendering a view with the name showcase-apply for the node type jnt:job. And the type of the view is “flow”, indicating that a dispatching to the Spring Web Flow controller is done for rendering the output.

2.3.3 Flow definition file

A single flow definition file, which by convention has the name flow.xml, is located in the view folder.

This file contains all the elements, required to describe and process the flows:

  • view states
  • transitions between views
  • action handlers
  • model binding and validation switches
  • etc.
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd
">
    <var name="handler" class="org.jahia.modules.webflow.showcase.JobApplicationHandler"/>
    <var name="jobApplication" class="org.jahia.modules.webflow.showcase.JobApplication"/>
    <view-state id="personal" model="jobApplication">
        <transition on="next" to="additional"/>
    </view-state>
    <view-state id="additional" model="jobApplication">
        <transition on="previous" to="personal" />
        <transition on="next" to="application" />
    </view-state>
    <view-state id="application" model="jobApplication">
        <transition on="previous" to="additional" />
        <transition on="next" to="summary" />
    </view-state>
    ...

Please, refer to “Chapter 3. Defining Flows” of the “Spring Web Flow Reference Guide” for the syntax and meaning of various flow definition elements: http://docs.spring.io/spring-webflow/docs/2.3.2.RELEASE/reference/html/ch03.html

2.3.4 Validation

Spring Web Flow supports advanced input validation on state transitions, also including JSR-303 (Bean Validation) support.

Here is an example of annotation-based validation:

public class JobApplication implements Serializable {

    @NotEmpty
    @Email
    private String email;

    private UploadedFile resume;

    private int salary;

    @DateTimeFormat(iso = ISO.DATE)
    private Date startingDate;

    @Pattern(regexp = "application/.*pdf")
    public String getCoverLetterContentType() {
        return coverLetter != null ? coverLetter.getContentType() : "application/pdf";
    }

    @Max(value = 1 * 1024 * 1024L)
    public long getCoverLetterLength() {
        return coverLetter != null ? coverLetter.getFile().length() : 0;
    }
   ...

3 Examples

In order to ease the start with the Spring Web Flow views in Digital Experience Manager various examples could be used, which are described in brief in the next sections.

3.1 Spring Web Flow showcase

This is a custom module for the Digital Experience Manager platform that shows the use of Spring Web Flow MVC technology for creating powerful content views, supporting automatic form data binding, advanced validation and integration of complex business processing logic.

Module source code: https://github.com/shyrkov/jahia-spring-webflow-showcase

Presentation slides (JahiaOne): http://www.slideshare.net/Jahia/112-jahia-onespringwebflow

Video recording of the presentation (JahiaOne): http://youtu.be/TUESY3l5XIw

3.2 Digital Experience Manager server and site panels

In Digital Experience Manager the Server and Site Administration parts were refactored using Spring Web Flow based views and move to the selector (left side panel) in edit mode.

All those management parts could serve also as a nice examples and quick-starts for your Web Flow development.

4 Summary

As a summary we will remind, what are the main application areas of the new Web Flow based views and what can be done with it:

  • Flow-based data processing
  • Validation
  • Complex business logic
  • External data / service integration

With this new powerful mechanism of data processing we have met our goals and our needs are covered.

Please, do not hesitate to send us your feedback or suggestions!