12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
12,530,443 members 60,129 online
articles
Q&A
Sign in
forums
lounge
Searchforarticles,questions,tips
A Simple CRUD Example with JSF
Dr. Song Li, 16 Sep 2015
CPOL
Rate this:
5.00 2 votes
This is a simple CRUD example with JSF.
Download JSFExample.zip 10.5 KB
Introduction
This is a simple CRUD example with JSF.
Background
JSF is an MVC framework, but it is very different from the Spring MVC and ASP.NET MVC. It actually has a strong ASP.NET Web
Form"POSTBACK" flavor. This example is based on astack overflow example.
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
1/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
The attached is a Maven project. I have tested it with Maven 3.2.1, Java 1.8.0_45, Tomcat 7, and Eclipse Java EE IDE for Web Developers
Luna Service Release 2. It actually has two examples.
The "simplecrud.xhtml" is the simple CRUD example;
The "freshsafecrud.xhtml" is to address the problems due to the JSF "POSTBACK" nature.
The "welcome.xhtml" is the index page of the two examples.
If you are not familiar with how to import Maven projects into Eclipse, you can check out this link. When I tried to import the project, I
noticed that Eclipse showed me some error message telling me some validation errors. You can simply ignore these messages and delete
the markers from Eclipse.
The pom.xml and the web.xml
The "pom.xml" declared the dependencies needed to create a JSF application.
Hide Shrink
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
Copy Code
2/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
<projectxmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.song.example</groupId>
<artifactId>JSFExample</artifactId>
<version>0.0.1SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<tomcat.version>7.0.55</tomcat.version>
<jsf.version>2.1.7</jsf.version>
</properties>
<dependencies>
<!Sevletjarsforcompilation,providedbyTomcat>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcatservletapi</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsfapi</artifactId>
<version>${jsf.version}</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsfimpl</artifactId>
<version>${jsf.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validationapi</artifactId>
<version>1.1.0.Final</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>mavencompilerplugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>mavenwarplugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
3/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
The "web.xml" of the example application is the following.
Hide Shrink
Copy Code
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"
id="WebApp_ID"version="3.0">
<displayname>JSFExample</displayname>
<welcomefilelist>
<welcomefile>welcome.xhtml</welcomefile>
</welcomefilelist>
<filter>
<filtername>nocachefilter</filtername>
<filterclass>
com.song.web.filter.NocacheFilter
</filterclass>
</filter>
<filtermapping>
<filtername>nocachefilter</filtername>
<urlpattern>/*</urlpattern>
</filtermapping>
<servlet>
<servletname>jsfservlet</servletname>
<servletclass>javax.faces.webapp.FacesServlet</servletclass>
<loadonstartup>1</loadonstartup>
</servlet>
<servletmapping>
<servletname>jsfservlet</servletname>
<urlpattern>*.xhtml</urlpattern>
</servletmapping>
<sessionconfig>
<sessiontimeout>20</sessiontimeout>
<trackingmode>COOKIE</trackingmode>
</sessionconfig>
<contextparam>
<paramname>BaseUrl</paramname>
<paramvalue>
http://localhost:8080/JSFExample/
</paramvalue>
</contextparam>
</webapp>
From a servlet container point of view, all the JSF pages will be mapped to the single servlet implemented by the
"javax.faces.webapp.FacesServlet" class;
In this example application, we mapped all the requests to all the "xhtml" pages to the "javax.faces.webapp.FacesServlet".
The Simple CRUD Example
The manage bean of the simple example is implemented in the "SimpleCrudBean" class.
Hide Shrink
Copy Code
packagecom.song.jsf.example;
importjava.io.IOException;
importjava.io.Serializable;
importjava.util.ArrayList;
importjava.util.List;
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
4/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
importjavax.annotation.PostConstruct;
importjavax.faces.bean.ManagedBean;
importjavax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
publicclassSimpleCrudBeanimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
privateList<Student>list;
privateStudentitem=newStudent();
privateStudentbeforeEditItem=null;
privatebooleanedit;
@PostConstruct
publicvoidinit(){
list=newArrayList<Student>();
}
publicvoidadd(){
//DAOsavetheadd
item.setId(list.isEmpty()?1:list.get(list.size()1).getId()+1);
list.add(item);
item=newStudent();
}
publicvoidresetAdd(){
item=newStudent();
}
publicvoidedit(Studentitem){
beforeEditItem=item.clone();
this.item=item;
edit=true;
}
publicvoidcancelEdit(){
this.item.restore(beforeEditItem);
this.item=newStudent();
edit=false;
}
publicvoidsaveEdit(){
//DAOsavetheedit
this.item=newStudent();
edit=false;
}
publicvoiddelete(Studentitem)throwsIOException{
//DAOsavethedelete
list.remove(item);
}
publicList<Student>getList(){
returnlist;
}
publicStudentgetItem(){
returnthis.item;
}
publicbooleanisEdit(){
returnthis.edit;
}
}
The "add", "saveEdit", and "delete" methods need to synchronize the data with a persistent storage like a database;
In this example, the database operation is skipped for simplicity.
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
5/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
The "Student" class is implemented in the "Student.java" file.
Hide Shrink
Copy Code
Hide Shrink
Copy Code
packagecom.song.jsf.example;
importjava.io.Serializable;
publicclassStudentimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
privateLongid;
privateStringname;
publicStudent(){}
publicStudent(Longid,Stringname){
this.id=id;
this.name=name;
}
publicLonggetId(){returnid;}
publicvoidsetId(Longid){this.id=id;}
publicStringgetName(){returnname;}
publicvoidsetName(Stringname){this.name=name;}
@Override
publicStudentclone(){
returnnewStudent(id,name);
}
publicvoidrestore(Studentstudent){
this.id=student.getId();
this.name=student.getName();
}
}
The "SimpleCrudBean" class is bound to the "simplecrud.xhtml" file to make it fully functional.
<!DOCTYPEhtml>
<htmlxmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>SimpleCRUD</title>
</head>
<body>
<h3>Liststudents</h3>
<h:formrendered="#{notemptysimpleCrudBean.list}">
<h:dataTablevalue="#{simpleCrudBean.list}"var="item">
<h:column><f:facetname="header">ID</f:facet>#{item.id}</h:column>
<h:column><f:facetname="header">Name</f:facet>#{item.name}</h:column>
<h:column>
<h:commandButtonvalue="edit"action="#{simpleCrudBean.edit(item)}"/>
</h:column>
<h:column>
<h:commandButtonvalue="delete"action="#{simpleCrudBean.delete(item)}"/>
</h:column>
</h:dataTable>
</h:form>
<h:panelGrouprendered="#{emptysimpleCrudBean.list}">
<p>Nostudents!Pleaseaddstudents.</p>
</h:panelGroup>
<h:panelGrouprendered="#{!simpleCrudBean.edit}">
<h3>Addstudent</h3>
<h:form>
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
6/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
<p>Name:<h:inputTextvalue="#{simpleCrudBean.item.name}"/></p>
<p>
<h:commandButtonvalue="add"action="#{simpleCrudBean.add}"/>
<h:commandButtonvalue="reset"action="#{simpleCrudBean.resetAdd}"/>
</p>
</h:form>
</h:panelGroup>
<h:panelGrouprendered="#{simpleCrudBean.edit}">
<h3>Editstudent#{simpleCrudBean.item.id}</h3>
<h:form>
<p>Name:<h:inputTextvalue="#{simpleCrudBean.item.name}"/></p>
<p>
<h:commandButtonvalue="save"action="#{simpleCrudBean.saveEdit}"/>
<h:commandButtonvalue="cancel"action="#{simpleCrudBean.cancelEdit}"/>
</p>
</h:form>
</h:panelGroup>
<p>
<ahref="#{appUrlStore.baseUrl}">Gobacktoindex</a>
</p>
</body>
</html>
If you now load the "simplecrud.xhtml" page, you can find that the CRUD operations all work fine. But if you click the refresh button on
the browser after adding a student, you will see this ugly popup message.
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
7/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
If you click the "Continue" button and proceed with the refresh, you will notice that the student just added gets added again. This is
definitely not a good behavior. This kind of behavior is due to the JSF's "POSTBACK" nature. In the next example, we will try to resolve
this issue.
The Refreshsafe CRUD Example
In order to address the problem in the simple CRUD example, I created the "CommonUtils" class.
Hide Shrink
Copy Code
packagecom.song.jsf.example.util;
importjava.io.IOException;
importjava.io.Serializable;
importjavax.faces.bean.ApplicationScoped;
importjavax.faces.bean.ManagedBean;
importjavax.faces.context.ExternalContext;
importjavax.faces.context.FacesContext;
importjavax.servlet.http.HttpServletRequest;
@ManagedBean(name="commonUtils")
@ApplicationScoped
publicclassCommonUtilsimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
publicvoidredirectWithGet(){
FacesContextfacesContext=FacesContext.getCurrentInstance();
ExternalContextexternalContext=facesContext.getExternalContext();
HttpServletRequestrequest=(HttpServletRequest)externalContext.getRequest();
StringBufferrequestURL=request.getRequestURL();
StringqueryString=request.getQueryString();
if(queryString!=null){
requestURL.append('?').append(queryString).toString();
}
Stringurl=requestURL.toString();
try{
externalContext.redirect(requestURL.toString());
}catch(IOExceptione){
thrownewRuntimeException("Unabletorerirectto"+url);
}
facesContext.responseComplete();
}
}
The "redirectWithGet" method is to simply send a redirect request to the browser to refresh the browser with a GET request. The
"CommonUtils" object is injected into the "FreshsafeCrudBean" class, and the "redirectWithGet" method is called whenever a
"POSTBACK" is performed.
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
8/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
Hide Shrink
Copy Code
packagecom.song.jsf.example;
importjava.io.IOException;
importjava.io.Serializable;
importjava.util.ArrayList;
importjava.util.List;
importjavax.annotation.PostConstruct;
importjavax.faces.bean.ManagedBean;
importjavax.faces.bean.ManagedProperty;
importjavax.faces.bean.SessionScoped;
importcom.song.jsf.example.util.CommonUtils;
@ManagedBean
@SessionScoped
publicclassFreshsafeCrudBeanimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
privateList<Student>list;
privateStudentitem=newStudent();
privateStudentbeforeEditItem=null;
privatebooleanedit;
@ManagedProperty(value="#{commonUtils}")
privateCommonUtilsutil;
publicvoidsetUtil(CommonUtilsutil){
this.util=util;
}
@PostConstruct
publicvoidinit(){
list=newArrayList<Student>();
}
publicvoidadd(){
//DAOsavetheadd
item.setId(list.isEmpty()?1:list.get(list.size()1).getId()+1);
list.add(item);
item=newStudent();
util.redirectWithGet();
}
publicvoidresetAdd(){
item=newStudent();
util.redirectWithGet();
}
publicvoidedit(Studentitem){
beforeEditItem=item.clone();
this.item=item;
edit=true;
util.redirectWithGet();
}
publicvoidcancelEdit(){
this.item.restore(beforeEditItem);
this.item=newStudent();
edit=false;
util.redirectWithGet();
}
publicvoidsaveEdit(){
//DAOsavetheedit
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
9/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
this.item=newStudent();
edit=false;
util.redirectWithGet();
}
publicvoiddelete(Studentitem)throwsIOException{
//DAOsavethedelete
list.remove(item);
util.redirectWithGet();
}
publicList<Student>getList(){
returnlist;
}
publicStudentgetItem(){
returnthis.item;
}
publicbooleanisEdit(){
returnthis.edit;
}
}
The "freshsafecrud.xhtml" is exactly the same as the "simplecrud.xhtml" file, except that it is bound to the "FreshsafeCrudBean" class.
If you now load the "simplecrud.xhtml", you should feel free to refresh you page without seeing the side effects of the "POSTBACK". Of
course the cost is a round trip to the web server.
Points of Interest
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
10/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
This is a simple CRUD example with JSF;
A true CRUD operation normally involves the database operations, but this example skipped them for simplicity;
JSF has a strongASP.NET Web Formflavor, it heavily relies on "POSTBACK" for its functionalities;
An additional example is also provided to address the side effects of the "POSTBACK" with the cost of an additional server round
trip.
History
First Revision 9/16/2015
License
This article, along with any associated source code and files, is licensed under The Code Project Open License CPOL
Share
EMAIL
TWITTER
About the Author
Dr. Song Li
United States
I have been working in the IT industry for some time. It is still exciting and I am still learning. I am a happy and honest person, and I
want to be your friend.
You may also be interested in...
RealLife Examples of how IBM DB2 with BLU
Acceleration is Creating Value for Enterprises
Microsoft Data Science Virtual Machine for
Windows and Linux now available
When Logging Isn't Enough: A Modern Approach to
Monitoring Performance in Production
Learnings from a DevOps Hackfest with Orckestra
10 Ways to Boost COBOL Application Development
SAPrefs Netscapelike Preferences Dialog
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
11/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
Comments and Discussions
You must Sign In to use this message board.
Search Comments
Go
First Prev Next
Java+JPA+JSF tutorials
Gerd Wagner 17Sep15 5:50
Re: Java+JPA+JSF tutorials
Dr. Song Li 17Sep15 5:55
Re: Java+JPA+JSF tutorials
Gerd Wagner 23Sep15 7:41
Re: Java+JPA+JSF tutorials
Dr. Song Li 25Sep15 3:43
Refresh
General
News
1
Suggestion
Question
Bug
Answer
Joke
Praise
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161010.2 | Last Updated 16 Sep 2015
Select Language
Article Copyright 2015 by Dr. Song Li
Everything else Copyright CodeProject, 19992016
Layout: fixed | fluid
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
12/12