JSF 2.0
JSF is a framework for building web applications using reusable components, and it’s focused on UI components. This allows you to write less HTML, which is a good thing.
What’s new compared to JSF 1.x?
- Annotations - faces-config.xml has less content or does not exist at all
- Support for Groovy
- A bit of convention over configuration (that also limits faces-config.xml content)
- Support for Ajax
- ... and more!
In this article
I will present basic configuration of a JSF 2.0 project with Maven. Nothing fancy.
Maven pom.xml
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.m1key.jsf</groupId> <artifactId>sample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <build> <finalName>sample</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.0.2-FCS</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-impl</artifactId> <version>2.0.2-FCS</version> <scope>provided</scope> </dependency> </dependencies> <repositories> <repository> <id>JBoss.org</id> <name>JBoss Repository</name> <url>http://repository.jboss.com/maven2</url> </repository> </repositories> </project>
Why those versions of JSF? Well, that’s exactly what JBoss 6.0.0-RC3 uses.
faces-config.xml
No faces-config.xml - we don’t need it!
Managed bean
package me.m1key.jsf; import javax.faces.bean.ManagedBean; @ManagedBean public class UserBean { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String send() { return "hello"; } }
Because we are using the @ManagedBean annotation, we don’t need to declare the bean anywhere else. You can override this configuration with faces-config.xml, if you need to.
The send() method returns a String “hello". Automatically, .xhtml is going to be appended to it and a view hello.xhtml will be resolved. No need to declare the rule. Convention over configuration.
The default scope of this bean is request. You can modify the default scope.
// ... // import javax.faces.bean.RequestScoped; import javax.faces.bean.SessionScoped; @ManagedBean // @RequestScoped @SessionScoped public class UserBean { // ...
- @RequestScoped
- @SessionScoped
- @ApplicationScoped - one bean for all
- @ViewScoped - the same bean is used as long as the user stays on the page (this is for AJAX)
- @CustomScoped - stores the bean in a map; developer controls it
- @NoneScoped - not in scope. Normally referenced by other beans that are in scope
Because it’s a managed bean, you can use JEE goodies (such as @EJB etc.) if you run your application on a JEE server .
Read more about managed beans validation and dependency injection using annotations.
I think that the JSF way of doing dependency injection is somewhat cumbersome. If you’re on JEE 6, you may want to use the new CDI mechanism. Jacek Laskowski wrote an article on using CDI with Java SEE (so without a JEE6 server). The article is in Polish, but the source code isn’t.
web.xml
<!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> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</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>*.xhtml</url-pattern> </servlet-mapping> </web-app>
Note the PROJECT_STAGE property. It’s new to JSF 2.0. You can read more about PROJECT_STAGE on Ryan Lubke’s blog.
The views
The view with a form:
<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <title>Index</title> </h:head> <h:body> <h:form> <h:inputText value="#{userBean.name}" /> <h:commandButton value="Send" action="#{userBean.send}" /> </h:form> </h:body> </html>
The result view:
<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <title>Hello</title> </h:head> <h:body> <h1>Hello #{userBean.name}</h1> </h:body> </html>
Summary
We created a simple JSF 2.0 application that uses a single managed bean and has 2 views. On that I will build another example, perhaps something using CDI.
Download source code for this article
hi,
ReplyDeleteout of curiosity I tried to rewrite pom.xml to Gradle (version 0.9-preview-3). This is the final build.gradle file:
apply plugin: 'war'
repositories {
mavenRepo urls: 'http://repository.jboss.com/maven2'
}
dependencies {
providedCompile 'javax.faces:jsf-api:2.0.2-FCS', 'javax.faces:jsf-impl:2.0.2-FCS'
}
The resulting WAR file is identical with the one generated by Maven (with one exception - no "maven" subfolder in META-INF).
--
Cheers,
Tomek Kaczanowski
Tomek, thanks a lot!
ReplyDeleteI still haven't looked into Gradle yet but I must (have you heard that Hibernate is switching to Gradle from Maven?).
The Gradle file looks more concise. Is Java 1.6 the default one?
Hi Michał,
ReplyDeletelol at Hibernate - it was me who posted this info on dzone :)
As for Java 1.6 - not sure about that but I think so.
--
Cheers,
Tomek
Okay, I see. :)
ReplyDeleteHave you gone Gradle too?