JBoss RichFaces with Spring
Let's start with BarBean class:
package bar.view;
import java.util.List;
import bar.service.Service;
public class BarBean {
private OrderService orderService;
@SuppressWarnings("unchecked")
public List getOrders () {
return orderService.getOrders();
}
public int getRowCount () {
return orderService.getOrders().size();
}
public Service getOrderService() {
return orderService;
}
public void setOrderService(Service orderService) {
this.orderService = orderService;
}
}
getOrders method calls the service class and returns all the orders.
getRowCount will return the number of rows. It's used not to render rich:dataTable component if the order is empty.
The other question is how do we get an instance of orderService into this bean. First, let's register this bean in Spring configuration file:
<bean id="barBean" class="bar.view.BarBean" scope="request"/>
We still have to deal with userService and how it gets initialized inside the bean. This is were Spring DI comes into play. We want Spring to inject userService into the barBean, when barBean is being created. To accomplish that, we modify the configuration to look like this:
<bean id="barBean" class="bar.view.BarBean" scope="request">
<property name="orderService" >
<ref bean="service" />
</property>
</bean>
service is the name under which we registered the Service class.
We are ready to look at WizardBean class. This class is the back end for the wizard.
package bar.view;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import org.hibernate.validator.Email;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.Pattern;
import bar.service.Service;
import bar.utils.JSFUtils;
public class WizardBean implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@NotEmpty(message = "Name must not be empty")
@Pattern(regex = ".*[^\\s].*", message = "This string contain only spaces")
private String name;
@NotEmpty
@Email(message = "Invalid email format")
private String email;
private String drink;
private String comments;
private String drinkCategorySelected;
private Service orderService;
private String startPage;
private List<SelectItem> drinkCategory;
private List<SelectItem> drinkList;
// init all drinks
private static final String [] CATEGORY = {"Brandy", "Rum", "Tequila", "Whiskey", "Wine", "Beer"};
private static final String [] BRANDY = {"XO", "VSOP", "VS"};
private static final String [] RUM = {"Medium", "Full-bodied", "Aromatic"};
private static final String [] TEQUILA = {"Reposado", "Añejo", "Blanco"};
private static final String [] WHISKEY = {"Malt", "Grain", "Single Malt", };
private static final String [] WINE = {"Red", "White", "Pink"};
private static final String [] BEER = {"Ales", "Lager", "Specialty Beer", };
public void changeDrink(ValueChangeEvent event) {
String newValue = (String) event.getNewValue();
if (newValue.equals("Brandy")) {drinkList = JSFUtils.createList(BRANDY); drink=BRANDY[0];}
else if (newValue.equals("Rum")) {drinkList = JSFUtils.createList(RUM); drink=RUM[0];}
else if (newValue.equals("Tequila")) {drinkList = JSFUtils.createList(TEQUILA);drink=TEQUILA[0];}
else if (newValue.equals("Whiskey")) {drinkList = JSFUtils.createList(WHISKEY);drink=WHISKEY[0];}
else if (newValue.equals("Wine")) {drinkList = JSFUtils.createList(WINE);drink=WINE[0];}
else if (newValue.equals("Beer")) {drinkList = JSFUtils.createList(BEER);drink=BEER[0];}
}
@PostConstruct
public void create() {
drinkCategorySelected = CATEGORY[0];
drinkCategory = JSFUtils.createList(CATEGORY);
drinkList = JSFUtils.createList(BRANDY);
drink = BRANDY[0];
}
public void save() {
orderService.addOrder(name, email, drink, comments);
this.startPage = "/page1.xhtml";
FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
.remove("wizardBean");
}
}
Don't forget to generate setters and getters for each property. I have omitted them in order to save space.
It looks like a lot more happening in this class, but in reality not that much. First, there are propeties such as email, name, drink and comments which correspond to different wizard screens. If you notice, they also correspond to Order model class.
email and name properties are annotated with Hibernate Validations annotations. We will come back to them when we build the pages.
The large section preceded by // init all drinks comment is how drinks list is created. It's not the most pretty way, but it will do for this example.
There is also JSF changeDrink value change listener. It will be invoked each time a new drink category is selected and will load the drinks associated with that category.
The save method saves the new order. The last line in save method removes the bean from request scope. We will come back to it shortly.
In this class as in BarBean, we have a reference to orderService. No where in the class we instantiate the property. You probably guessed, but we are going to use Spring's DI to inject the service into this bean. Let's register this bean in Spring configuratin file.
<bean id="wizardBean" class="bar.view.WizardBean" scope="request">
<property name="startPage" value="/page1.xhtml"/>
<property name="orderService" >
<ref bean="service" />
</property>
</bean>
startPage property is initialized to the first page in the wizard.
orderService is injected with service bean.
One last class is the JSFUtils:
package bar.utils;
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.SelectItem;
public class JSFUtils {
public static List <SelectItem> createList (String [] data){
ArrayList <SelectItem>list = new ArrayList <SelectItem>();
for (String item : data){
list.add (new SelectItem (item, item));
}
return list;
}
}
This only method in this class creates a list of SelectItem's. We are ready to create the views.
| Attachment | Size |
|---|---|
| richfaces-spring-wizard.zip | 11.15 MB |
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Gene De Lisa replied on Fri, 2009/07/31 - 9:45am
What exactly are you thinking by posting an 11 MB zip file that contains nothing but library jar files? Are you getting some perverse pleasure by wasting other people's time and bandwidth? Do you know the meaning of the word courtesy? Apparently not.
If you don't want to post your code don't post a zip. It's as simple as that.
Kushan Jayathilake replied on Fri, 2009/10/30 - 7:56am
Hi Max, Great work!..
i have a problem, i have added the validation conditions in managed bean of the JSF page
ie :
i have several <a4j:commandButton> and <a4j:commandLink> in the same page, validation fires each and every time i press a commandLink or Button, iif that field is empty("countryName" as i specified here)
how can i control the validation to fire for the particular button or a link...? (i need validation to be fired when only i clicked the save button)
please help me on this...
Max Katz replied on Thu, 2009/11/05 - 8:10pm
in response to:
Kushan Jayathilake
Kushan Jayathilake replied on Fri, 2009/11/06 - 6:45am
I have another question,
I want to generate dynamic checkboxes depends on a collection, so i have written
<h:dataTable id="functionsGrid" value="# {functionManagedBean.collecOfFunctions}" var="function" > <h:column> <h:selectBooleanCheckbox id="#{function.functionName}" value="#{functionManagedBean.checked}"/> <h:outputLabel for="" value="outputLabel"></h:outputLabel> </h:column> </h:dataTable>and finally this form contains an <a4j:commandButton> , in the managedBean side i want to get the selected checkboxes....(problem is checkboxes are generating dyamically, so how can assign their values for the different properties in the managedBean..
Thank you very much in advance.. :)
Tee Siong replied on Wed, 2010/04/07 - 5:40am
Thomas Strecker replied on Thu, 2010/05/27 - 3:36am
in response to:
Mohsin Khan
I encountered the same problem, but only after switching to Spring Annotations and Component Scan. The reason is rather simple: the WizardBean now no longer receives the value for the startPage (which was set to "/page1.xhtml" in the spring application context before) and now the renderer ends up in a endless loop.
So if you want to use the annotation based version, manually set the parameter in the bean.
Mohammad Shariq replied on Tue, 2010/06/15 - 2:50pm
Mehdi Ben Haj Abbes replied on Mon, 2010/07/19 - 2:18am
in response to:
stu bilton
Fabio Malheiro replied on Tue, 2010/09/28 - 8:26am
This was supposed to be a good tutorial right?
I was trying to implement your example... but I'm a little bit confused. Sometimes you "talk" about a bean orderService, and Service ... but where the fuck is the Service class?
Andres Botero replied on Wed, 2010/11/17 - 12:02pm
When i inyect a dependency into a bean it's null. For Example:
<bean id="wizardBean" class="bar.view.WizardBean" scope="request">
<property name="orderService" >
<ref bean="service" />
</property>
</bean>
In that case the orderService is null, colud you tell me why is that?
A S M Russel replied on Fri, 2011/09/30 - 1:10am
After Migrating from XML configuration to Annotation based configurated i am getting the following error.
at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)
the error trace is too long thats why i am pasting it here.
I create the spring3 template project with STS and follow your instruction.
Its working well for xml configuration.But getting error when i am going to annotation based configuration
Scott Duke replied on Tue, 2011/10/25 - 10:46pm
Max Katz replied on Thu, 2011/10/27 - 4:48pm
in response to:
Scott Duke
Nagy Andika replied on Fri, 2011/11/04 - 5:13am