In this article we will try to build an entire skull of jsf2/spring4 application, welwill use hibernate4 to manage persistency, use bundles for internalization and primefaces 5 in view layer.The application will be mavenized.
The result architecture will have this behavior:
The result architecture will have this behavior:
- First Step is to create a maven project based on webapp archtype(how to work with maven nad elipse ?1
mvn archetype:generate -DgroupId=com.itillusion.travel -DartifactId=travel -Dpackagename=com.itillusion.travel -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.0 -DinteractiveMode=
false
this link is useful by A.Mekki) - Next step is to add correct dependencies for artifacts that we'll use.to our pom.xml
MySQL jdbc connector
Hibernate4 (requires dbcp2)
Spring4
Primefaces5
JSF 2 api/impl and servlet
we will add also repositories
our pom.xml will be
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198<
project
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://maven.apache.org/POM/4.0.0"
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
>com.itillusion</
groupid
>
<
artifactid
>travel</
artifactid
>
<
version
>0.0.1-SNAPSHOT</
version
>
<
packaging
>war</
packaging
>
<
properties
>
<
spring
.framework.version
=
""
>4.1.3.RELEASE</
spring
>
<
spring
.security.version
=
""
>3.2.5.RELEASE</
spring
>
<
hibernate
.framework.version
=
""
>4.3.7.Final</
hibernate
>
<
primefaces
.framework.version
=
""
>5.1</
primefaces
>
</
properties
>
<
dependencies
>
<!-- MySQL -->
<
dependency
>
<
groupid
>mysql</
groupid
>
<
artifactid
>mysql-connector-java</
artifactid
>
<
version
>5.1.6</
version
>
</
dependency
>
<!-- MySQL -->
<!-- Hibernate -->
<
dependency
>
<
groupid
>org.hibernate</
groupid
>
<
artifactid
>hibernate-core</
artifactid
>
<
version
>${hibernate.framework.version}</
version
>
</
dependency
>
<!-- Hibernate -->
<!-- Primefaces -->
<
dependency
>
<
groupid
>org.primefaces</
groupid
>
<
artifactid
>primefaces</
artifactid
>
<
version
>${primefaces.framework.version}</
version
>
</
dependency
>
<!-- /Primefaces -->
<!-- Spring framework -->
<
dependency
>
<
groupid
>org.springframework</
groupid
>
<
artifactid
>spring-context</
artifactid
>
<
version
>${spring.framework.version}</
version
>
</
dependency
>
<
dependency
>
<
groupid
>org.springframework</
groupid
>
<
artifactid
>spring-web</
artifactid
>
<
version
>${spring.framework.version}</
version
>
</
dependency
>
<
dependency
>
<
groupid
>org.springframework</
groupid
>
<
artifactid
>spring-orm</
artifactid
>
<
version
>${spring.framework.version}</
version
>
</
dependency
>
<!-- Spring framework -->
<!-- Jsf -->
<
dependency
>
<
groupid
>com.sun.faces</
groupid
>
<
artifactid
>jsf-api</
artifactid
>
<
version
>2.1.2</
version
>
</
dependency
>
<
dependency
>
<
groupid
>com.sun.faces</
groupid
>
<
artifactid
>jsf-impl</
artifactid
>
<
version
>2.1.2</
version
>
</
dependency
>
<!-- Jsf -->
<!-- Servlets -->
<
dependency
>
<
groupid
>javax.servlet</
groupid
>
<
artifactid
>servlet-api</
artifactid
>
<
version
>2.5</
version
>
<
scope
>provided</
scope
>
</
dependency
>
<!-- Servlets -->
<!-- apache dbcp -->
<
dependency
>
<
groupid
>org.apache.commons</
groupid
>
<
artifactid
>commons-dbcp2</
artifactid
>
<
version
>2.0</
version
>
</
dependency
>
<!-- apache packs -->
<!-- JUnit 3.8.1 -->
<
dependency
>
<
groupid
>junit</
groupid
>
<
artifactid
>junit</
artifactid
>
<
version
>3.8.1</
version
>
<
scope
>test</
scope
>
</
dependency
>
<!-- JUnit 3.8.1 -->
</
dependencies
>
<
repositories
>
<
repository
>
<
id
>JSFRepo</
id
>
<
name
>Repository for JSF2</
name
>
<!-- <layout>default</layout>-->
</
repository
>
<
repository
>
<
id
>MavenRepo</
id
>
<
name
>Repository for Maven2</
name
>
<!-- <layout>legacy</layout>-->
</
repository
>
<
repository
>
<
id
>prime-repo</
id
>
<
name
>PrimeFaces Maven Repository</
name
>
<
layout
>default</
layout
>
</
repository
>
<
repository
>
<
id
>maven-repository.dev.java.net</
id
>
<
name
>Java Dev Net Repository</
name
>
<
releases
>
<
enabled
>true</
enabled
>
<
updatepolicy
>never</
updatepolicy
>
</
releases
>
<
snapshots
>
<
enabled
>false</
enabled
>
</
snapshots
>
</
repository
>
<
repository
>
<
id
>spring-milestone</
id
>
<
name
>Spring Portfolio Milestone Repository</
name
>
</
url
>
</
repository
>
<
repository
>
<
id
>spring-snapshot</
id
>
<
name
>Spring Portfolio snapshot Repository</
name
>
</
repository
>
<
repository
>
<
id
>jboss-repo</
id
>
<
name
>jboss Repository</
name
>
</
repository
>
<
repository
>
<
id
>java.net</
id
>
<
name
>Java.net Repository for Maven2</
name
>
</
repository
>
<
repository
>
<
id
>spring-ext</
id
>
<
name
>Spring External Dependencies Repository</
name
>
</
url
>
</
repository
>
<
repository
>
<
releases
>
<
enabled
>true</
enabled
>
</
releases
>
<
snapshots
>
<
enabled
>false</
enabled
>
<
updatepolicy
>never</
updatepolicy
>
</
snapshots
>
<
id
>repository.jboss.com</
id
>
<
name
>Jboss Repository for Maven</
name
>
<
layout
>default</
layout
>
</
repository
>
<
repository
>
<
id
>jboss-public-repository-group</
id
>
<
name
>JBoss Public Repository Group</
name
>
</
repository
>
</
repositories
>
</
project
>
Note here we have used version properties to make pom more evolutive
in1<
spring.security.version
>3.2.5.RELEASE</
spring.security.version
>
- Next step is to configure web.xml (typical jsf webapp, web.xml with listner for spring)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748<
web-app
id
=
"WebApp_ID"
version
=
"3.0"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xsi:schemalocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>
<
display-name
>travel</
display-name
>
<
welcome-file-list
>
<
welcome-file
>index.html</
welcome-file
>
<
welcome-file
>index.htm</
welcome-file
>
<
welcome-file
>index.jsp</
welcome-file
>
<
welcome-file
>default.html</
welcome-file
>
<
welcome-file
>default.htm</
welcome-file
>
<
welcome-file
>default.jsp</
welcome-file
>
</
welcome-file-list
>
<!-- Change to "Production" when you are ready to deploy -->
<
context-param
>
<
param-name
>javax.faces.PROJECT_STAGE</
param-name
>
<
param-value
>Development</
param-value
>
</
context-param
>
<!-- JSF servlet mappings -->
<
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
>
<
url-pattern
>*.xhtml</
url-pattern
>
</
servlet-mapping
>
<!-- JSF servlet mappings -->
<!-- spring listener -->
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
</
listener
>
<!-- spring listener -->
<!-- spring context params -->
<
context-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>/WEB-INF/applicationContext.xml</
param-value
>
</
context-param
>
<!-- spring context params -->
</
web-app
>
- Now we write our faces-config.xml, thanks to annotation, this configuration file is too lightWe have used here a resource-bundle to manage internalization of messages and labels:12345678910111213141516
<
faces-config
version
=
"2.1"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xsi:schemalocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"
>
<
application
>
<
locale-config
>
<
default-locale
>fr</
default-locale
>
</
locale-config
>
<
resource-bundle
>
<
base-name
>com.itillusion.travel.internalization.language</
base-name
>
<
var
>language</
var
>
</
resource-bundle
>
<
el-resolver
>org.springframework.web.jsf.el.SpringBeanFacesELResolver</
el-resolver
>
</
application
>
</
faces-config
>
In this line:<
base-name
>com.itillusion.travel.internalization.language</
base-name
>
we told to jsf that our file is located in package com.itillusion.travel.internalizationand its name is language.properties
NB: language.properties is a resource file: it must be located under WEB-INF/classes in deployement folder :
here under eclipse we have configured in deployement assembly onglet a copy of src/main/resources to WEB-INF/classes
language.properties contains these few lines: applicationTitle=Traveler
companyName=Itillusion
userId=ID Utilisateur
userName=Nom utilisateur
- Now we go ahead to applicationContext.xml which contains declaration of spring beans and hibernate properties.
In order to seperate real configuration from database access configuration we will put database access informations in a separate file called jdbc.properties under WEB-INF. folder
We have told to spring that we will work with annotation and application beans will be in sub packages of "com.itillusion.travel
<context:component-scan base-package="com.itillusion.travel" />
We have to tell hibenate where he will find models
<property name="packagesToScan" value="com.itillusion.travel.model" />
Here is a complete applicationContext.xmland here is the listing of jdbc.properties1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253<
beans
xmlns:aop
=
"http://www.springframework.org/schema/aop"
xmlns:context
=
"http://www.springframework.org/schema/context"
xmlns:tx
=
"http://www.springframework.org/schema/tx"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://www.springframework.org/schema/beans"
xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<
context:annotation-config
>
<
context:component-scan
base-package
=
"com.itillusion.travel"
>
<!-- Hibernate relates beans and properties -->
<
bean
class
=
"org.springframework.orm.hibernate4.LocalSessionFactoryBean"
id
=
"sessionFactory"
>
<
property
name
=
"hibernateProperties"
>
<
props
>
<!-- <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>-->
<
prop
key
=
"hibernate.dialect"
>org.hibernate.dialect.MySQLDialect</
prop
>
<
prop
key
=
"hibernate.show_sql"
>true</
prop
>
<
prop
key
=
"hibernate.cache.use_query_cache"
>false</
prop
>
</
props
>
</
property
>
<!-- entities -->
<
property
name
=
"packagesToScan"
value
=
"com.itillusion.travel.model"
>
<
property
name
=
"dataSource"
>
<
ref
bean
=
"dataSource"
>
</
ref
></
property
>
</
property
></
bean
>
<
bean
class
=
"org.apache.commons.dbcp2.BasicDataSource"
destroy-method
=
"close"
id
=
"dataSource"
lazy-init
=
"true"
>
<
property
name
=
"driverClassName"
value
=
"${jdbc.driverClassName}"
>
<
property
name
=
"url"
value
=
"${jdbc.url}"
>
<
property
name
=
"username"
value
=
"${jdbc.username}"
>
<
property
name
=
"password"
value
=
"${jdbc.password}"
>
<
property
name
=
"validationQuery"
value
=
"select 1 "
>
<
property
name
=
"testOnBorrow"
value
=
"True"
>
</
property
></
property
></
property
></
property
></
property
></
property
></
bean
>
<!-- where are stored connexion properties(login,pwd,server,..) -->
<
bean
class
=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
id
=
"propertyConfigurer"
>
<
property
name
=
"locations"
>
<
list
>
<
value
>/WEB-INF/jdbc.properties</
value
>
</
list
>
</
property
>
</
bean
>
<!-- /Hibernate -->
<!-- Enable the configuration of transactional behavior based on annotations -->
<
tx:annotation-driven
transaction-manager
=
"transactionManager"
>
<!-- Transaction Manager is defined -->
<
bean
class
=
"org.springframework.orm.hibernate4.HibernateTransactionManager"
id
=
"transactionManager"
>
<
property
name
=
"sessionFactory"
ref
=
"sessionFactory"
>
</
property
></
bean
>
</
tx:annotation-driven
></
context:component-scan
></
context:annotation-config
></
beans
>
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/travel
jdbc.username=travel
jdbc.password=yourpassword
- Now we have the choice : finish the view layer with its facelets or attack an entity to display it in th view layer.
Personally i prefer finish the view for a simple reason :
When a standard page of our application is displayed, then any problem that will appear in integration of any page will be the result of a programmation mistake.
Ok, we continue,
we start by th building of a template for the application:
A- create a folder templates and under it a folder common.
B- Create the commonLayout.xhtml file that will descibe the design of a common page in the application, in our casse commonLayout is composed by 3 files a header, a content and a footer (here we have a one column deisgn).
here is the listing of the 4 files:
commonLayout.xhtml:
commonHeader.xhtml:1234567891011121314151617181920212223242526<
h:head
>
<
h:outputstylesheet
library
=
"css"
name
=
"common-style.css"
>
</
h:outputstylesheet
></
h:head
>
<
h:body
>
<
div
id
=
"page"
>
<
div
id
=
"header"
>
<
ui:insert
name
=
"header"
>
<
ui:include
src
=
"commonHeader.xhtml"
>
</
ui:include
></
ui:insert
>
</
div
>
<
div
id
=
"content"
>
<
ui:insert
name
=
"content"
>
<
ui:include
src
=
"commonContent.xhtml"
>
</
ui:include
></
ui:insert
>
</
div
>
<
div
id
=
"footer"
>
<
ui:insert
name
=
"footer"
>
<
ui:include
src
=
"commonFooter.xhtml"
>
</
ui:include
></
ui:insert
>
</
div
>
</
div
>
</
h:body
>
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071<
ui:composition
>
<!-- common header -->
<
div
class
=
"head-panel"
>
<
div
class
=
"application-logo"
>
<
h:form
>
<
p:graphicimage
styleclass
=
"logo-img"
value
=
"/resources/img/common/traveler.jpg"
>
</
p:graphicimage
></
h:form
>
</
div
>
<
div
class
=
"slogon"
>
#{language.applicationTitle}</
div
>
<
div
class
=
"time-panel"
>
<
h:form
>
<
p:clock
mode
=
"server"
pattern
=
"dd.MM.yyyy HH:mm:ss"
>
</
p:clock
></
h:form
>
</
div
>
</
div
>
<!-- /common header -->
<!-- menu -->
<
div
class
=
"menu-panel"
>
<
h:form
>
<
p:growl
id
=
"messages"
>
<
p:menubar
>
<
p:submenu
icon
=
"ui-icon-document"
label
=
"File"
>
<
p:submenu
icon
=
"ui-icon-contact"
label
=
"New"
>
<
p:menuitem
url
=
"#"
value
=
"Project"
>
<
p:menuitem
url
=
"#"
value
=
"Other"
>
</
p:menuitem
></
p:menuitem
></
p:submenu
>
<
p:menuitem
url
=
"#"
value
=
"Open"
>
<
p:separator
>
<
p:menuitem
url
=
"#"
value
=
"Quit"
>
</
p:menuitem
></
p:separator
></
p:menuitem
></
p:submenu
>
<
p:submenu
icon
=
"ui-icon-pencil"
label
=
"Edit"
>
<
p:menuitem
icon
=
"ui-icon-arrowreturnthick-1-w"
url
=
"#"
value
=
"Undo"
>
<
p:menuitem
icon
=
"ui-icon-arrowreturnthick-1-e"
url
=
"#"
value
=
"Redo"
>
</
p:menuitem
></
p:menuitem
></
p:submenu
>
<
p:submenu
icon
=
"ui-icon-help"
label
=
"Help"
>
<
p:menuitem
url
=
"#"
value
=
"Contents"
>
<
p:submenu
icon
=
"ui-icon-search"
label
=
"Search"
>
<
p:submenu
label
=
"Text"
>
<
p:menuitem
url
=
"#"
value
=
"Workspace"
>
</
p:menuitem
></
p:submenu
>
<
p:menuitem
url
=
"#"
value
=
"File"
>
</
p:menuitem
></
p:submenu
>
</
p:menuitem
></
p:submenu
>
<
p:submenu
icon
=
"ui-icon-gear"
label
=
"Actions"
>
<
p:submenu
icon
=
"ui-icon-refresh"
label
=
"Ajax"
>
<
p:menuitem
actionlistener
=
"#{menuView.save}"
icon
=
"ui-icon-disk"
update
=
"messages"
value
=
"Save"
>
<
p:menuitem
actionlistener
=
"#{menuView.update}"
icon
=
"ui-icon-arrowrefresh-1-w"
update
=
"messages"
value
=
"Update"
>
</
p:menuitem
></
p:menuitem
></
p:submenu
>
<
p:submenu
icon
=
"ui-icon-newwin"
label
=
"Non-Ajax"
>
<
p:menuitem
actionlistener
=
"#{menuView.delete}"
ajax
=
"false"
icon
=
"ui-icon-close"
update
=
"messages"
value
=
"Delete"
>
</
p:menuitem
></
p:submenu
>
</
p:submenu
>
<
f:facet
name
=
"options"
>
<
p:inputtext
placeholder
=
"Search"
style
=
"margin-right: 10px;"
>
<
p:commandbutton
icon
=
"ui-icon-extlink"
type
=
"button"
value
=
"Logout"
>
</
p:commandbutton
></
p:inputtext
></
f:facet
>
</
p:menuitem
></
p:menubar
>
</
p:growl
></
h:form
>
</
div
>
<!-- /menu -->
</
ui:composition
>
commonContent.xhtml:12345678<
ui:composition
>
<
ui:insert
name
=
"content"
>
<
h1
>
This is default content</
h1
>
</
ui:insert
>
</
ui:composition
>
12345678<
ui:composition
>
<
div
class
=
"footer-panel"
>
</
div
>
</
ui:composition
>
Note that next the composition called content in the commonContent.xhtml will be overrided each time a page is shown
C- add the index.jsp page that will redirect to a default xhtml page that will be considered a the entry point of the application.
index.jsp under the root(webapp):1<
jsp:forward
page
=
"faces/editUsers.xhtml"
></
jsp:forward
>
our application will show directly a listing of users inserted previously in database.
css and js files have to be under folder resources under webapp otherways they will not be loaded. - Now we will create the different layers of the application:
a model layer
a dao layer
a service layer
a managedbeans layer to interact with jsf views
Considering that we have a mysql 3 tables under schema travel with this descriptions:
12345678910111213141516171819202122232425262728293031323334353637383940mysql> show tables;
+------------------+
| Tables_in_travel |
+------------------+
| profile |
| user_profile |
| utilisateur |
+------------------+
3 rows
in
set
(3.36 sec)
mysql> describe utilisateur;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| usr_id | int(11) | NO | PRI | NULL | auto_increment |
| usr_login | varchar(45) | YES | | NULL | |
| usr_pwd | varchar(45) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
3 rows
in
set
(2.76 sec)
mysql> desc profile;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| prf_id | int(11) | NO | PRI | NULL | auto_increment |
| prf_lib | varchar(45) | NO | UNI | NULL | |
+---------+-------------+------+-----+---------+----------------+
2 rows
in
set
(0.28 sec)
mysql> desc user_profile;
+---------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+----------------+
| usrprf_id | int(11) | NO | PRI | NULL | auto_increment |
| prf_id | int(11) | NO | MUL | NULL | |
| usr_id | int(11) | NO | MUL | NULL | |
| usrprf_active | int(11) | NO | | 0 | |
+---------------+---------+------+-----+---------+----------------+
4 rows
in
set
(2.53 sec)
-
Model layer (just one class (utilisateur))
Note we will this tree of packages and classes
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182package
com.itillusion.travel.model;
// Generated 25 nov. 2014 14:54:59 by Hibernate Tools 3.4.0.CR1
import
java.util.HashSet;
import
java.util.Set;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.FetchType;
import
javax.persistence.GeneratedValue;
import
static
javax.persistence.GenerationType.IDENTITY;
import
javax.persistence.Id;
import
javax.persistence.OneToMany;
import
javax.persistence.Table;
/**
* Utilisateur generated by hbm2java
*/
@Entity
@Table
(name =
"utilisateur"
, catalog =
"travel"
)
public
class
Utilisateur
implements
java.io.Serializable {
/**
*
*/
private
static
final
long
serialVersionUID = 8276067938930706574L;
private
Integer usrId;
private
String usrLogin;
private
String usrPwd;
private
Set<userprofile> userProfiles =
new
HashSet<userprofile>(
0
);
public
Utilisateur() {
}
public
Utilisateur(String usrLogin, String usrPwd,
Set<userprofile> userProfiles) {
this
.usrLogin = usrLogin;
this
.usrPwd = usrPwd;
this
.userProfiles = userProfiles;
}
@Id
@GeneratedValue
(strategy = IDENTITY)
@Column
(name =
"usr_id"
, unique =
true
, nullable =
false
)
public
Integer getUsrId() {
return
this
.usrId;
}
public
void
setUsrId(Integer usrId) {
this
.usrId = usrId;
}
@Column
(name =
"usr_login"
, length =
45
)
public
String getUsrLogin() {
return
this
.usrLogin;
}
public
void
setUsrLogin(String usrLogin) {
this
.usrLogin = usrLogin;
}
@Column
(name =
"usr_pwd"
, length =
45
)
public
String getUsrPwd() {
return
this
.usrPwd;
}
public
void
setUsrPwd(String usrPwd) {
this
.usrPwd = usrPwd;
}
@OneToMany
(fetch = FetchType.LAZY, mappedBy =
"utilisateur"
)
public
Set<userprofile> getUserProfiles() {
return
this
.userProfiles;
}
public
void
setUserProfiles(Set<userprofile> userProfiles) {
this
.userProfiles = userProfiles;
}
}
</userprofile></userprofile></userprofile></userprofile></userprofile>
-
Dao layer, all classes under com.itillusion.travel.dao are interfaces, who knows if we will change hibernate by another orm ?
implementations are under com.itillusion.travel.dao.impl
First of all web begin with generic dao classes: GenericDao.java
an implementation of this class is12345678910111213package
com.itillusion.travel.dao;
import
java.io.Serializable;
import
java.util.List;
public
interface
GenericDao<t
extends
=
""
i=
""
serializable=
""
> {
public
T find(I id);
public
List<t> findAll();
public
void
delete(T obj);
public
void
saveOrUpdate(T obj);
}
</t></t>
NB: this class is under impl subpackage.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960package
com.itillusion.travel.dao.impl;
import
java.io.Serializable;
import
java.util.List;
import
org.hibernate.SessionFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.transaction.annotation.Transactional;
import
com.itillusion.travel.dao.GenericDao;
public
abstract
class
GenericDaoImpl<t
extends
=
""
i=
""
serializable=
""
>
implements
GenericDao<t i=
""
>{
@Autowired
SessionFactory sessionFactory;
private
Class<t> type;
public
GenericDaoImpl(Class<t> type){
this
.type = type;
}
public
void
setSessionFactory(SessionFactory sessionFactory) {
this
.sessionFactory = sessionFactory;
}
public
SessionFactory getSessionFactory() {
return
sessionFactory;
}
@SuppressWarnings
(
"unchecked"
)
@Transactional
(readOnly =
true
)
@Override
public
T find(I id) {
return
(T) getSessionFactory().getCurrentSession().get(type, id);
}
@SuppressWarnings
(
"unchecked"
)
@Transactional
(readOnly =
true
)
public
List<t> findAll(){
return
(List<t>) getSessionFactory().getCurrentSession().createQuery(
"from "
+type.getName()).list();
}
@Transactional
@Override
public
void
delete(T obj) {
getSessionFactory().getCurrentSession().delete(obj);
}
@Transactional
@Override
public
void
saveOrUpdate(T obj) {
getSessionFactory().getCurrentSession().saveOrUpdate(obj);
}
}
</t></t></t></t></t></t>
@Autowired annotation is present to ensure the injection of sessionFactory bean
Now wel will create an interface for UserDao ; here we don't need anything expect methods in GenericDao
123456789package
com.itillusion.travel.dao;
import
com.itillusion.travel.model.Utilisateur;
public
interface
UserDao
extends
GenericDao<utilisateur nteger=
""
> {
}
</utilisateur>
a possible implementation for this interface is
Note the presence og @Repository annotation it's needed for dao bean injection in service bean123456789101112131415161718package
com.itillusion.travel.dao.impl;
import
org.springframework.stereotype.Repository;
import
com.itillusion.travel.dao.UserDao;
import
com.itillusion.travel.model.Utilisateur;
@Repository
public
class
UserDaoImpl
extends
GenericDaoImpl<utilisateur nteger=
""
>
implements
UserDao {
public
UserDaoImpl(){
super
(Utilisateur.
class
);
}
public
UserDaoImpl(Class<utilisateur> type) {
super
(type);
}
}
</utilisateur></utilisateur>
Ok now we have set the Dao layer. - We pass to service layer: same idea it will be interfaces for eache service and one/many implementation for each interface
let's start with user interface
12345678910111213package
com.itillusion.travel.service;
import
java.util.List;
import
com.itillusion.travel.model.Utilisateur;
//since we willl only display list of users
public
interface
UserService {
public
List<utilisateur> getUsers();
}
</utilisateur>
a possible implementation for this interface is
Note the presence of @Service annotation needed for service object injection in the managed bean1234567891011121314151617181920212223242526272829303132333435package
com.itillusion.travel.service.impl;
import
java.util.List;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service;
import
com.itillusion.travel.dao.UserDao;
import
com.itillusion.travel.model.Utilisateur;
import
com.itillusion.travel.service.UserService;
@Service
public
class
UserServiceImpl
implements
UserService {
@Autowired
UserDao userDao;
@Override
public
List<utilisateur> getUsers() {
return
userDao.findAll();
}
public
UserDao getUserDao() {
return
userDao;
}
public
void
setUserDao(UserDao userDao) {
this
.userDao = userDao;
}
}
</utilisateur>
- Last step is to create our managedbean !
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758package
com.itillusion.travel.beans;
import
java.io.Serializable;
import
java.util.List;
import
javax.annotation.PostConstruct;
import
javax.faces.bean.ManagedBean;
import
javax.faces.bean.SessionScoped;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Component;
import
com.itillusion.travel.model.Utilisateur;
import
com.itillusion.travel.service.UserService;
@Component
@ManagedBean
(name=
"listUsersBean"
)
@SessionScoped
public
class
ListUsersBean
implements
Serializable {
/**
*
*/
private
static
final
long
serialVersionUID = 6675856254221490117L;
@Autowired
private
UserService authService;
private
List<utilisateur> users;
@PostConstruct
public
void
init() {
System.out.println(authService);
users = authService.getUsers();
}
public
List<utilisateur> getUsers() {
return
users;
}
public
void
setUsers(List<utilisateur> users) {
this
.users = users;
}
public
UserService getAuthService() {
return
authService;
}
public
void
setAuthService(UserService authService) {
this
.authService = authService;
}
}
</utilisateur></utilisateur></utilisateur>
We will now display all users :), then we will return to our application and we will create a folder called faces under the webapp and create our xhtml page editUsers.xhtml
- we have that then :
just a remark; if you want to use primefaces themes or skins
- go to this url -
- comments are welcome!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | < h:body > < ui:composition template = "../templates/common/commonLayout.xhtml" > < ui:define name = "content" > <!-- Specific content --> < h:form > < p:datatable id = "tbl" paginator = "true" paginatortemplate = "{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {Exporters}" rows = "10" style = "margin-bottom: 20px;" value = "#{listUsersBean.users}" var = "user" > < f:facet name = "{Exporters}" > < h:commandlink > < p:graphicimage value = "/resources/img/tools/excel.png" width = "24" > < p:dataexporter filename = "users" target = "tbl" type = "xls" > </ p:dataexporter ></ p:graphicimage ></ h:commandlink > < h:commandlink > < p:graphicimage value = "/resources/img/tools/pdf.png" width = "24" > < p:dataexporter filename = "users" target = "tbl" type = "pdf" > </ p:dataexporter ></ p:graphicimage ></ h:commandlink > < h:commandlink > < p:graphicimage value = "/resources/img/tools/csv.png" width = "24" > < p:dataexporter filename = "users" target = "tbl" type = "csv" > </ p:dataexporter ></ p:graphicimage ></ h:commandlink > < h:commandlink > < p:graphicimage value = "/resources/img/tools/xml.png" width = "24" > < p:dataexporter filename = "users" target = "tbl" type = "xml" > </ p:dataexporter ></ p:graphicimage ></ h:commandlink > </ f:facet > < p:column > < f:facet name = "header" > < h:outputtext value = "#{language.userId}" > </ h:outputtext ></ f:facet > < h:outputtext value = "#{user.usrId}" > </ h:outputtext ></ p:column > < p:column > < f:facet name = "header" > < h:outputtext value = "#{language.userName}" > </ h:outputtext ></ f:facet > < h:outputtext value = "#{user.usrLogin}" > </ h:outputtext ></ p:column > </ p:datatable > </ h:form > <!-- End specific content --> </ ui:define > </ ui:composition > </ h:body > |