jsf 2 2.0 jboss tutorial wenJSF 2.0 is a major upgrade over JSF 1.2. The major additions include ManagedBeans annotations, simplified navigation and Ajax Support. In this first article we will look at the first two additions, using the milestone 3 of JBoss AS 6.
At first you need a JBoss AS release which is compatible with JSF 2.0 API  ( JBoss AS 6/7 run by default a JSF 2 API implementation).

JSF Managed Beans Annotations

Let's start. One of the most useful additions of JSF 2.0 is the ability to add annotations for your Beans instead of using the file faces-config.xml. You might think there it's going on a religious war against XML configuration files- it's not so.
Actually using annotations simplifies the management of your projects because you don't need to lock/share a file which is used by all your developers, every time you need to add a bean or a navigation rule.

Let's show an example:
 
  package sample;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="person", eager="true")
@RequestScoped

public class PersonBean {

    String personName;
    String prompt;
    String email;
    int amount;
    
     public PersonBean() {
        this.prompt="Enter your name please";
    }

    public int getAmount() {
        return amount;
    }
    public void setAmount(int amount) {
        this.amount = amount;
    }
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }


    public String getPrompt() {
        return prompt;
    }

    public void setPrompt(String prompt) {
        this.prompt = prompt;
    }


    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String name) {
        personName = name;
    }
    public void doSomething() {
        personName= personName.toUpperCase();
    }
     
}
In this example we have tagged our Bean as ManagedBean by using the annotation @ManagedBean.
We have set the attribute name to define how we will reference the bean in our Jsp pages and the attribute eager = true, which means that the Bean will be instantiated at application startup and not when it's first referenced.
If you don't specify the name attribute, the Bean will be bound using the Class name, with the first letter in lowercase. If you don't specify the eager attribute it will default to false.
The other annotation we have added is @RequestScoped which means the Bean is bound in the Request.
All possible alternatives are:
  • @NoneScoped 
  • @RequestScoped 
  • @ViewScoped 
  • @SessionScoped 
  • @ApplicationScoped 
  • @CustomScope

What is the View Scope ? View Scope has been introduced in JSF 2.0 and it's particularly useful when you are editing some objects while staying in the same page. In other words it's something broader then request but smaller then session, since this scope terminates if you navigate to other pages.

  Here is a sample tutorial which shows how to create a CRUD applications using JSF and @ViewScoped.

Now Let's add a basic JSP page which will be used in our example:
 

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"       xmlns:f="http://java.sun.com/jsf/core"       xmlns:h="http://java.sun.com/jsf/html">

<h:body>
   <f:view>   
      
     <h:form id="helloForm">
     <h:outputText value="#{person.prompt}" />
          
     <h:inputText id="name" value="#{person.personName}" />
     <h:commandButton value="go" action="#{person.doSomething}" />

     </h:form>
   </f:view>
 </h:body>
</html>

What happened to JSP Tags?

One thing you might have noticed is the absence of standard JSP tags. As a matter of fact, JSP technology is considered to be a deprecated presentation technology for Java Server Faces 2.0. That simply means, that JSF preferred view technology is Facelets, for an introduction to Facelets have a look at this tutorial.
By running this trivial example, the command button will trigger the action doSomething which will uppercase the attribute. Let's complete the example adding a basic web.xml and faces.config.

Here's the web.xml:
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <context-param>
        <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
        <param-value>true</param-value>
    </context-param>

    <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>*.jsf</url-pattern>
    </servlet-mapping>
</web-app>
And the faces-config.xml just needs:
 
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" 
          version="2.0"> 
</faces-config>
Notice the attribute version="2.0". If you use by mistake a faces-config.xml with the attribute set to "1.2" or "1.0", the code will run with the earlier JSF release.


Adding validation to your pages

You now have several options to validate your components. If you need a simple validation rule, you can use the basic f:validate options like in this example:
 
<h:inputText id="amount" value="#{person.amount}" >
      <f:validateLength maximum="10" />
</h:inputText>
If you need a more complex rule, you can demandate to your bean the validation:
 
 <h:inputText id="email" value="#{person.email}"
      validator="#{personBean.validateEmail}" >
</h:inputText>


    
public void validateEmail(FacesContext context, UIComponent validated,Object value) {
          String mail = (String) value;        
          if (!mail.matches(".+\\@.+\\..+")) {            
              FacesMessage msg = new FacesMessage("This is not an e-mail!");              context.addMessage(validated.getClientId(context),msg);            throw new ValidatorException(msg);        
          }    
}


Better and simpler navigation

Another add-on in JSF 2.0, is that now supports implicit navigation, which can now be addresses directly in the JSP file, like in this example:
 
<h:commandButton value="Press me!" action="nextPage"/>

This will cause the JSF engine to invoke a page named nextPage in the same directory of the current page.
In our example, nextPage.jsp will be invoked. You can also specify full page name, if you have multiple pages with the same name in the same directory. 
 
<h:commandButton value="Press me!" action="nextPage.xhtml"/>

If the page where we need to navigate is located in another directory, you can obviously use the standard path convention:
 
<h:commandButton value="Press me!" action="/subdir/anotherPagel"/>
 
You might think that the file faces-config.xml is pretty useless at this point. It's not true, as a matter of fact an important add-on in JSF 2.0 is the ability to perform conditional navigation. By using conditional navigation you can get rid of navigations detail from your JSF Beans, where you will concentrate exclusively on the model that the Bean incarnates. 

Let's see a practical example:
 
<navigation-rule>
        <from-view-id>/home.jsp</from-view-id>
        <navigation-case>
            <from-action>#{person.action}</from-action>
            <if>#{person.validationOk}</if>
            <to-view-id>/done.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-action>#{person.action}</from-action>
            <if>#{!person.validationOk}</if>
            <to-view-id>/error.jsp</to-view-id>
        </navigation-case>
</navigation-rule>


 
public void action() {
    if (name != null && name.trim().length() > 0) 
        validationOk = true;
    else
        validationOk = false;
}
In this example, instead of returning the next view from the method action() of the Class Person, we just set the property validationOk. Then the configuration file will decide where to navigate depending on the value of the property.

Finally, another opportunity offered by JSF 2 is the ability to issue a redirect when you invoke an action. The default action before now was to issue a forward, which is surely more efficient but sometimes you might need to redirect the navigation to a new page.
A typical example is where you have issues releated to the Refresh browser button, which might cause problems to your application if the address on the navigation bar is not consistent with the actual state of the application.

With JSF 2 you can just add the parameter faces-redirect=true to enable page redirection.
 
<h:commandLink  action="/sample?faces-redirect=true" value="Click"/>
 
Reference to next articles:
0
0
0
s2sdefault