Sunteți pe pagina 1din 12

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

S-ar putea să vă placă și