Flow4J-Struts Integration

The following sections describe the advantages of using Flows as the Controller part of the Struts framework and a detailed description how to integrate Flow4J in Struts.

You can see live samples at Flow4J-Struts Samples

The WAR File and the Sources are avalilable too.

Note:

There may be some features in Struts which cannot be handled by Flow4J currently. In this case send me message , and I'll do my best.

Motivation

The Flow4J framework contains a Servlet that dispatches a user request directly to a specific flow. All the request parameters are put in the Flow Dictionary as String. This is all fine, but the user has to code the validation stuff and has to care that in the case of validation errors the old values are again displayed for further correction.

Thus Flow4J represents the controller in the MVC pattern itself but cannot compete with some others like the Apache Struts framework which offers nice and useful features like validation and a rich tag library to access information in Form Beans. I personally don't like Struts very much because it becomes more and more a mammoth and tries to cover too much aspects of web application programming. What IMO is very complicated in Struts is all this XML configuration and the fact that each Action has to return a forward mapping that is directly tied to a resource like a JSP page, and unfortunately this mapping again has to be declared in XML form. Cha ining many Struts actions together is also only possible by XML.

Idea

At this point comes the idea to use Struts features like Form Beans, their validation and even tiles, but replace single Actions by complete Flows. So the whole business process is not only one Action class that is a non-visualizable sequence of method calls, but a complete Flow that can execute a number of tasks and can even contain flow controlling functionality like decisions, jumps, and joins.

The fact that Flows have one or more well defined entry points (Start Flowlets) and can return a template or resource name, makes it possible to transfer many Struts configuration information out of the struts-config.xml file directly into the flow, where they belong.

Almost all URLs which trigger the Struts controller have the following pattern:

http://server/context/someaction.do

This requires a mapping in the struts-config.xml file. The Flow4J-Struts integration simplifies this:

http://server/context/SomeFlow-Start.do

This URL pattern is much more self explaining and requires no manual configuration because the framework automatically recognizes which Flow to execute. Let's see the details and the possibilities to involve Form Beans and validation in the next section.

Realisation

The main building parts of the Struts framework are

  • Action Forms aka. Form Beans and
  • Actions

developers normally declare them in the struts-config.xml file.

In Flow4J the Action's path is the Flow's entry point , the Start Flowlet. And the Form Bean's name and type are provided as Start Flowlet properties .

In the Flow4J Designer, Start Flowlets have a dynamically extendable property list. This means that you specify a c omma separated list of property names, and Eclipse generates the Property Descriptors automatically. In the the next picture you can see the properties of the Start Flowlet "Check".

In the property "Property names (comma separated)", three properties are defined:

  • action-input
  • form-bean-name
  • form-bean-type

These properties are needed to teach Struts what to do if the user calls the following URL:

http://server/context/Login-Check.do?user=...&password=...

The advantage of this way of Struts configuration is that all information that belongs together is kept together . That's why the declaration of the Form Bean's name and type is done directly in the Start Flowlet. BTW a Flow can have more than one entry point (Start Flowlet) thus the possibility is also given to declare different Form beans for the different Start Flowlets of the same Flow.

Flow4J is very tolerant and gives priority to all information that Struts gets out of the struts-config.xml file. This means that you can distribute Form Bean and Action informations between the Flow and the struts-config.xml file. Thus there exist the following two possibilities to declare a Form Bean:

  • declare the Form Bean's type and name in the Start Flowlet
  • declare name in the StartFlowlet and name/type in the struts-config.xml file.

If the type is declared in both locations, and they are not the same, then an exception is thrown.

Technical Acpects

Flow4J uses the Struts API to register all Actions and ActionForms. For this reason all Flows which are registered at the FlowManager are scanned for available Start Flowlets. For every Start Flowlet of a Flow, Actions are generated and registered. To accomplish all the registrations Flow4J overrides the regular ActionServlet with the net.orthanc.flow4j.runtime.connectors.struts.Flow4JActionServlet class, which registers all Actions in all Struts modules.

So the Flow shown in the last picture would register the following Actions at every Struts module:

  • /Login-Form
  • /Login-Check

In this case Flow4J is tolerant again, you can declare additional information in the struts-config.xml file eg. for the Action Mapping with the path "/Login-Form". But if nothing else is specified the config file, the Action's type is by default net.orthanc.flow4j.runtime.connectors.struts.Flow4JAction . This class extends the Struts Action class and executes the appropriate Flow. If the Struts config file declares a type for a specific Action like "/Login-Check" then of course this class' execute() method is executed.

configuration

The configuration of the web applicaion is quite the same as with the other Flow4J Servlets. The Servlet type is the extended ActionServlet and the FlowRepository is supported in the for of an initialization parameter.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd"> 
<web-app>  
  <display-name>Flow4j-Struts demonstration</display-name>
  
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>net.orthanc.flow4j.runtime.connectors.struts.Flow4JActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/config/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>flow-repository-class</param-name>
      <param-value>net.orthanc.flow4struts.FlowRepository</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  ...
</web-app> 
			

All needed classes are in the file flow4jruntime.jar inside the plugin folder.