I use Apache Trinidad at work and since JSF 2 is now final I decided to play with it a bit.
Of course this is going to be the classic Hello World example (as there are many other like this around the web).
First you need to setup a simple Maven project.
The file layout should be something like that.

Directory Layout for JSF 2 Ajax Demo
After that change your pom.xml to include the servlet and jsf2 libs.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.maxheapsize</groupId>
<artifactId>jsf2demo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>jsf2demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.0-b13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.0-b13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<finalName>jsf2demo</finalName>
</build>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
</project>
First we are going to create the managed bean to hold the name we are going to enter.
package com.maxheapsize.jsf2demo;
import javax.faces.bean.*;
import java.io.Serializable;
@ManagedBean
@SessionScoped
public class HelloWorldBean implements Serializable {
private String name = "";
@ManagedProperty(value = "#{demoService}")
private Service service;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setService(Service service) {
this.service = service;
}
public String getReverseName() {
return service.reverse(name);
}
}
To demonstrate the dependency injection with JSF 2 I use a service to reverse the name. Simply add the @ManagedProperty with the name of the service and it will get injected. Of course we need the service. Here it is:
package com.maxheapsize.jsf2demo;
import javax.faces.bean.*;
@ManagedBean(name="demoService")
@ApplicationScoped
public class Service {
public String reverse(String name) {
return new StringBuffer(name).reverse().toString().toLowerCase();
}
}
Very simple…isn’t it ?
The only thing what’s missing is the web.xml and the webpage itself.
The web.xml is pretty straight forward and should not show any surprises.
<!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>Web Application</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
The index.xhtml has some differences from earlier versions of JSF. First, JSF now supports Ajax out of the box. To have this enabled you need to load the jsf.js javascript library. The inputText tag binds to our managed bean and includes an f:ajax tag. This tag determines which part should be rerendered (in this case the element with the id reverseName). F:ajax will execute on value holding components always with an ‘onchange’ event and on action components (like commandButtons) with an ‘onclick’ event.
The output will trigger the injected service in our managed bean and return the reversed input string.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>JSF Demo</title>
</h:head>
<h:body>
<h:outputScript name="jsf.js" library="javax.faces" target="body">
</h:outputScript>
<h1>Ajax JSF 2 Demo</h1>
<h:form>
<h:inputText id="name" value="#{helloWorldBean.name}">
<f:ajax render="reverseName"/>
</h:inputText>
<h:commandButton value="Say reverse Hi via Ajax">
<f:ajax execute="name" render="reverseName"/>
</h:commandButton>
<h:outputText id="reverseName" value="#{helloWorldBean.reverseName}"/>
</h:form>
</h:body>
</html>

JSF 2 Ajax Demo
And that’s it. Sure it’s a simple example, but so far I do like the minimal configuration and the ajax integration.
In the last couple of month I was writing some flows using Spring Webflow 2. I knew that I (in theory) I could test them but I never did. The overall documentation of Webflow 2 is not that great at the moment, so I hope to improve that a little bit.
Spring Webflow 2 supports only JUnit tests so far. I guess this will change at some point but until then you have to pull out that junit.jar again.
Sorry for the awkward line breaks. Spring just does love long method and class names (which is not that bad).
Your Testclass needs to extends AbstractXmlFlowExecutionTests and to implement protected FlowDefinitionResource getResource(FlowDefinitionResourceFactory resourceFactory).
public class MyWebflowTest extends AbstractXmlFlowExecutionTests
protected FlowDefinitionResource getResource(
FlowDefinitionResourceFactory resourceFactory) {
FlowDefinitionResource flowDefinitionResource =
resourceFactory.createResource("flows/administration/skinManagement.flow.xml");
return flowDefinitionResource;
}
If your flow now happen to have a parent flow you are in a bit of trouble. You just can include one flow in the FlowDefinitionResource. The parent tag in your flow points to an id of the parentflow which is usually defined in a webflow configuration file. If this parent flow again has parents as well…yes, same game again.
To get a hold of these flows you need to override getModelResources[].
@Override
protected FlowDefinitionResource[]
getModelResources(FlowDefinitionResourceFactory resourceFactory) {
FlowDefinitionResource[] flowDefinitionResources =
new FlowDefinitionResource[3];
flowDefinitionResources[0] =
resourceFactory.createResource("flows/common.flow.xml");
flowDefinitionResources[1] =
resourceFactory.createResource("flows/common-exceptionHandling.flow.xml");
flowDefinitionResources[2] =
resourceFactory.createResource("flows/common-menu.flow.xml");
return flowDefinitionResources;
}
If one of your flows is using beans you want to mock them in the test. You can do that by registering with the MockFlowBuildContext. The method configureFlowBuilderContext will be called by AbstractXmlFlowExecutionTests
@Override
protected void configureFlowBuilderContext(
MockFlowBuilderContext builderContext) {
builderContext.registerBean("validationExceptionHandler",
new ValidationExceptionHandler());
builderContext.registerBean("infastructureExceptionHandler",
new InfastructureExceptionHandler());
builderContext.registerBean("springSecurityExceptionHandler",
new SpringSecurityExceptionHandler());
}
With this setup you now can start testing the flow.
...
public void testSkinManagementView() {
MockExternalContext mockExternalContext = new MockExternalContext();
startFlow(mockExternalContext);
assertFlowExecutionActive();
assertCurrentStateEquals("showSkinManagementOverview");
}
...
I think the code is pretty self explanatory.
You have several possibilities including start and resume flow and assert certain states. You can test action methods doing something (like calling a service) and making sure the correct flow is executed.
Figuring out the initial setup with the parent flow and beans was the most time consuming task. You need to make sure that you only put flow logic in the definition of the flow since that is what webflow is for. I think with some clever usage of set and result you can make things complicated and a bit tricky.