Wednesday, December 31, 2014

Spring4 / Hibernate4 / JSF2 / Primefaces5 jee web application skull

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:



  1. First Step is to create a maven project based on webapp archtype

    1
    mvn archetype:generate -DgroupId=com.itillusion.travel -DartifactId=travel -Dpackagename=com.itillusion.travel -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.0 -DinteractiveMode=false
    (how to work with maven nad elipse ?
     this link is useful by A.Mekki)
  2. 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


    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
      <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
    in 
    1
    <spring.security.version>3.2.5.RELEASE</spring.security.version>
  3. Next step is to configure web.xml (typical jsf webapp, web.xml with listner for spring)

    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
      <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>

  4. Now we write our faces-config.xml, thanks to annotation, this configuration file is too light

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
         
         
        <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>
    We have used here a resource-bundle to manage internalization of messages and labels:
    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

  5. 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.xml
    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
             
         
          
      <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>
    and here is the listing of jdbc.properties
    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/travel
    jdbc.username=travel
    jdbc.password=yourpassword

  6. 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:
    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
        <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>
    commonHeader.xhtml:
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
         
         <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>
          
                <p:menuitem icon="ui-icon-close" url="http://www.primefaces.org" value="Quit">
          
                <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:
    1
    2
    3
    4
    5
    6
    7
    8
         
         <ui:composition>
          <ui:insert name="content">
           <h1>
    This is default content</h1>
    </ui:insert>
         </ui:composition>
        

    1
    2
    3
    4
    5
    6
    7
    8
         
         <ui:composition>
      
       <div class="footer-panel">
        Traveler v1.0- (C) <a href="http://www.itillusion.com/">IT ILLUSION</a> -2014-
       </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.
  7. 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:
    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
    mysql>  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)
  8. Model layer (just one class (utilisateur))

    Note we will this tree of packages and classes


    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    package 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>
  9. 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package 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>
    an implementation of this class is
    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
    54
    55
    56
    57
    58
    59
    60
    package 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>
    NB: this class is under impl subpackage.
    @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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    package 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package 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>
    Note the presence og @Repository annotation it's needed for dao bean injection in service bean
    Ok now we have set the Dao layer.
  10. 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package 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
    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
    package 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>
    Note the presence of @Service annotation needed for service object injection in the managed bean
  11. Last step is to create our managedbean !
    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
    54
    55
    56
    57
    58
    package 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>
  12. 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
    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>
  13. we have that then :

    just a remark; if you want to use primefaces themes or skins
    - go to this url -

  14. comments are welcome!