- Spring WF 1.X API | Spring WF 1.X Reference Guide | Spring WF Practical Intro | Spring WF 1.X Reference Apps | Spring 1.X WF YouTube | Spring WF1 Wiki Article | Spring WF 1 Examined | Spring WF 1 Starter
- Spring WF 1 with Grails
- Spring WF 1 – Struts2
There seems to be in package org.springframework.webflow.action a FlowAction and a FlowExecutor class. As well, the ExternalContext class which is credited to allowing WF to be decoupled from Servlet API .
- Spring WF 2.0.X API | Spring WF 2.0.X Reference Guide | Spring WF 2.0.X Reference Apps | Spring 2 WF Example
I do not see a FlowAction or FlowExecutor in org.spring.webflow.action package like in webflow 1.
Instead, lets look at what we have from the example Spring Flow 2.0 Example application.
To use annotations for the transactions within the example, we do the following:
- Put an tag tx:annotation-driven in the spring config file
- Put @Transactional annotation in the services classes
@Transactional – The @Transactional annotation may be placed before an interface definition, a method on an interface, a class definition, or a public method on a class. However, please note that the mere presence of the @Transactional annotation is not enough to actually turn on the transactional behavior.
You can actually omit the ‘transaction-manager’ attribute in the <tx:annotation-driven/> tag if the bean name of the PlatformTransactionManager that you want to wire in has the name ‘transactionManager’.
<!– Instructs Spring to perfrom declarative transaction managemenet on annotated classes –>
<!– Drives transactions using local JPA APIs –>
<bean id=”transactionManager” class=”org.springframework.orm.jpa.JpaTransactionManager”/>
The LocalContainerEntityManagerFactoryBean can be configured with all Persistent Unit information like is done here.
@PersistenceUnit – annotated on EntityManagerFactory instances are thread-safe
<!– Creates a EntityManagerFactory for use with the Hibernate JPA provider and a simple in-memory data source populated with test data –>
<bean id=”entityManagerFactory” class=”org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean”>
<!– Deploys a in-memory datasource –>
<bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
<property name=”driverClassName” value=”org.hsqldb.jdbcDriver”/>
<property name=”url” value=”jdbc:hsqldb:mem:tutorialSwf”/>
<property name=”username” value=”sa”/>
<property name=”password” value=””/>
<!– Activates annotation-based bean configuration –>
Mapping URLs to Handlers – maps request URLs to handlers. A simple way to create URL mapping rules is to define one as follows:
<!– Maps request URIs to controllers –>
<!– Selects view names to render based on the request URI: e.g. /main selects “main” –>
The Flow Handler manages executions of a single flow definition. Above the handler selects view based on the URI in a default handler. To Implement one, extend
Flow Controller – The FlowHandler MVC integration approach, you define one handler per flow. This is overkill in the cases where default flow handling rules are sufficient. Web controller for the Spring web MVC framework that routes incoming requests to one or more managed web flows. Requests into the web flow system are managed using a configurable
<!– Handles requests mapped to the Spring Web Flow system –>
<bean id=”flowController” class=”org.springframework.webflow.mvc.servlet.FlowController“/>
The flow executor is the core Web Flow configuration element. Flow execution listeners are also defined in the flow executor.
<!– Executes flows: the central entry point into the Spring Web Flow system –>
FlowRegistry – placed where you register your flows
flow-builder-services attribute – customize the services used to build the flows in a registry…When the tag is defined, you only need to reference the services you want to customize.
<!– The registry of executable flow definitions –>
<webflow:flow-registry id=”flowRegistry” flow-builder-services=”facesFlowBuilderServices”>
flow scoped persistence context – provides isolation of intermediate edits by only committing changes to the database at the end of flow execution. This pattern is often used in conjunction with an optimistic locking strategy to protect the integrity of data modified in parallel by multiple users.
@PersistenceContext – annotated on EntityManager instances are not thread safe
<flow xmlns=”http://www.springframework.org/schema/webflow” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
configure the correct FlowExecutionListener in this case for JPA
<!– Installs a listener that manages JPA persistence contexts for flows that require them –>
<bean id=”jpaFlowExecutionListener” class=”org.springframework.webflow.persistence.JpaFlowExecutionListener”>
Here is how they handle the view:
<!– Maps logical view names to Facelet templates (e.g. ‘search’ to ‘/WEB-INF/search.xhtml’ –>
<bean id=”faceletsViewResolver” class=”org.springframework.web.servlet.view.UrlBasedViewResolver”>
<property name=”viewClass” value=”org.springframework.faces.mvc.JsfView”/>
<property name=”prefix” value=”/WEB-INF/”/>
<property name=”suffix” value=”.xhtml”/>
Or a simple ViewResolver
I have been an Eclipse user most of my Java career. Though, I do have limited experience with Visual Age, Forte, JBuilder, and Netbeans. In the Eclipse space, it has been WSAD, MyEclipse, Eclipse WTP (2.x,3.2, Europa 3.3), and RAD 6/7.
Part of NFJS exposed me to IntelliJ. Here is one take on this IDE.
Spring 2.0 introduced support for various annotations for configuration purposes, such as:
- @Transactional – The @Transactional annotation may be placed before an interface definition, a method on an interface, a class definition, or a public method on a class. However, please note that the mere presence of the @Transactional annotation is not enough to actually turn on the transactional behavior.
- @Required – used to mark a property as being ‘required-to-be-set’ (i.e. an annotated (setter) method of a class must be configured to be dependency injected with a value)
- @PersistenceContext – annotated on EntityManager instances are not thread safe
- @PersistenceUnit – annotated on EntityManagerFactory instances are thread-safe
Thus, to use annotations for the transactions for my purposes, I do the following:
- Put an tag tx:annotation-driven in the config file (i.e applicationContext.xml)
- Put @Transactional annotation in the services class implementation that contains operations on the entity manager
- @Autowired in combination with support for the JSR-250 annotations @Resource
On the Spring Web Flow (SWF) vision from 1.x to 2.x :
“[in 1.0] the SWF controller engine cared for one half of the web request lifecycle; the half related to request processing, often called the action phase. The other half, the render phase, was pushed off on the caller: either Spring MVC, Struts, or JSF front controllers
The downside of this approach is it makes it difficult to apply application control logic during the view rendering phase
Beginning with Web Flow 2.0 M2, the entire web request lifecycle is now under the control of Spring Web Flow, including the view rendering phase.
the ability for the SWF engine to communicate with external systems and conversational contexts over HTTP (embedding the proper flow execution callback URL in the redirect that is sent to the external system)”
Also, note that getting these Spring Flow 2.x reference sample projects are easy to get a hold of. In the download of Web Flow is a projects/build-spring-webflow directory where you can run ant. It will build Web Flow along with the .war files for the sample projects (ant 1.7 and Java 5 are required to build).
As far as further examples than the ones above, I found some web flow 2.x examples at this site spring by example.
Spring flow 1.0 showed that it could easily integrate with struts. These sample (1.x) applications can also be found on Java Passion Site. A good 1.x reference is the Practical ntroduction . All the samples projects are Spring IDE projects that importable into Eclipse (see springide or plugin central for spring ide).
Here in the 1.x struts example:
Our first action in the jsp is as follows:
<A href=”flowAction.do?_flowId=birthdate”>Birth Date</A>
This action in the struts config says:
<action path=”/flowAction” name=”actionForm” scope=”request” type=”org.springframework.webflow.executor.struts.FlowAction”/>
We also bind to the Action Form:
<form-bean name=”actionForm” type=”org.springframework.web.struts.SpringBindingActionForm”/>
In the webflow-config.xml we define the flow registry:
<flow:executor id=”flowExecutor” registry-ref=”flowRegistry”/>
<!– Creates the registry of flow definitions for this application –>
Start State : the first state in the flow
<start-state idref=”enterBirthdate” />
View State: selects a view to render
<view-state id=”enterBirthdate” view=”birthdateForm”>
When the execution of the flow starts, enter the enterBirthdate state. Then select the birthdateForm view for display to the user, and pause the flow of execution until a user event happens.
Render Action: initializes the form object.
<action bean=”formAction” method=”setupForm” />
For view state, above Initializes the backing “form object” by invoking the setupForm method for formAction.
Note that the action was defined in the webflow-config.xml (instance of spring-webflow-config-1.0.xsd)
<bean id=”formAction” class=”org.springframework.webflow.samples.birthdate.BirthDateFormAction” />
Transition: Each View state must define a transition that leads to another state
<transition on=”submit” to=”processBirthdateFormSubmit” />
Action state: logic that needs to be executed in context of the request, once executed the result flow is returned which the flow may respond to.
<action bean=”formAction” method=”bindAndValidate”>
<attribute name=”validatorMethod” value=”validateBirthdateForm” />
transition on=”success” to=”enterCardInformation” />
<transition on=”error” to=”enterBirthdate” />
Related Links for Basic info on JSF:
- Introducing Java Server Faces (JSF) to 4GL Developers
- JSRs: 127, 252 (1.2)
- An Introduction to JSF
- JSF Hello World
I have used derby a while back. Several years later, I wanted to get it installed again on my machine.
In short, Derby is the Java Database that IBM contributed to the open source community. It was known then as cloudscape.
I start off by getting the bin download from the derby database
create DERBY_HOME environment variable : C:\JAVA\derby10\db-derby-10.2.2.0-bin\
Make sure I have my JAVA_HOME environment variable properly set
add to the PATH: C:\JAVA\derby10\db-derby-10.2.2.0-bin\bin\
from the command line:
ij is the derby sql client command line
.tools.sysinfo -cp embedded SimpleApp.class
FOUND IN CLASS PATH:
Derby embedded engine library (derby.jar)
user-specified class (SimpleApp)
SUCCESS: All Derby related classes found in class path.
get ibm jars for derby
C:\JAVA\derby10\db-derby-10.2.2.0-bin\demo\programs\simple>java SimpleApp jccjdb
SimpleApp starting in jccjdbc mode.
Loaded the appropriate driver.
Connected to and created database derbyDB
Created table derbyDB
Inserted 1956 Webster
Inserted 1910 Union
Updated 1956 Webster to 180 Grand
Updated 180 Grand to 300 Lakeshore
Verified the rows
Dropped table derbyDB
Closed result set and statement
Committed transaction and closed connection
/* the default framework is embedded*/
public String framework = “embedded”;
public String driver = “org.apache.derby.jdbc.EmbeddedDriver”;
public String protocol = “jdbc:derby:”;
public static void main(String args)
void go(String args)
/* parse the arguments to determine which framework is desired*/
System.out.println(“SimpleApp starting in ” + framework + ” mode.”);
The driver is installed by loading its class.
In an embedded environment, this will start up Derby, since it is not already running.
System.out.println(“Loaded the appropriate driver.”);
Connection conn = null;
Properties props = new Properties();
The connection specifies create=true to cause
the database to be created. To remove the database,
remove the directory derbyDB and its contents.
The directory derbyDB will be created under
the directory that the system property
derby.system.home points to, or the current
directory if derby.system.home is not set.
conn = DriverManager.getConnection(protocol +
System.out.println(“Connected to and created database derbyDB”);
Creating a statement lets us issue commands against
Statement s = conn.createStatement();
We create a table, add a few rows, and update one.
private void parseArguments(String args)
int length = args.length;
for (int index = 0; index < length; index++)
framework = “jccjdbc”;
driver = “com.ibm.db2.jcc.DB2Driver”;
protocol = “jdbc:derby:net://localhost:1527/”;
framework = “derbyclient”;
driver = “org.apache.derby.jdbc.ClientDriver”;
protocol = “jdbc:derby://localhost:1527/”;