A Simple CRUD Example With JSF - CodeProject
A Simple CRUD Example With JSF - CodeProject
ASimpleCRUDExamplewithJSFCodeProject
articles
Q&A
Sign in
forums
lounge
Searchforarticles,questions,tips
CPOL
Rate this:
5.00 2 votes
This is a simple CRUD example with JSF.
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.
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
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".
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
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.
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
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
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.
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
11/12
12/10/2016
ASimpleCRUDExamplewithJSFCodeProject
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
http://www.codeproject.com/Articles/1030872/ASimpleCRUDExamplewithJSF
12/12