Skip to main content

2. Create a Maven JSF project and a simple login page

Updated on Oct-25-2107

0. Introduction


Remember to install previously:

  1. Java JDK 8
  2. Eclipse Oxygen
  3. Lombok 
  4. Apache Tomcat 9

1. Create a Maven Project

In the top menu select :

File - New - Maven Project



Press Next

Now fill the next form as follows

It is important to select:
  1. Group id: org.ximodante.jsf (or another packet you like)
  2. Packaging: war
  3. Artifact Id and Name: JSFv02 or any name for the project

Press Finish

2. The pom.xml file

Eclipse complains about the simple generated file. It seems that a web.xml is required if the packaging is selected to war.

The simple generated file is 


1
2
3
4
5
6
7
8
9
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>org.ximodante.jsf</groupId>
  <artifactId>JSFv02</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>JSFv02</name>
  <description>Second project</description>
</project>


That should be replaced with this one



 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
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         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>org.ximodante.jsf</groupId>
  <artifactId>JSFv02</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>JSFv02</name>
  <description>JSF Second project</description>
  
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>
  
  
  <dependencies>
       
    <!-- Servlet-api -->
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax-servlet-api</artifactId>
      <version>4.0.0</version>
    </dependency>
    
    
    <!--  JSF 2.3.3 OracleImplementation -->
    <!-- https://mvnrepository.com/artifact/org.glassfish/javax.faces -->
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.faces</artifactId>
      <version>2.3.3</version>
    </dependency>
    

    <!--  Primefaces -->
    <dependency>
     <groupId>org.primefaces</groupId>
     <artifactId>primefaces</artifactId>
     <version>6.1</version>
    </dependency>

    
    <!-- Weld CDI for Tomcat with all dependencies included (does not fulfill all capabilities !!!) -->
    <dependency>
      <groupId>org.jboss.weld.servlet</groupId>
      <artifactId>weld-servlet-shaded</artifactId>
      <version>3.0.1.Final</version>
    </dependency>
    
        
    <!-- Validation API Optional -->
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.0.Final</version>
    </dependency>
        
    <!-- Hibernate Bean Validator Optional -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.2.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.18</version>
      <scope>provided</scope>
    </dependency>
    
    
  </dependencies>
</project>


3. Additional files:

1. Create a new folder into webapp folder called WEB-INF

2. Create an empty file beans.xml in the WEB-INF folder. This file may be required by CDI (Context and dependency injection). For more information see BalusC.

3. Create the file faces-config.xml in the WEB-INF folder. This file is referenced in coreservlets from Marti Hall


1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 
              xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">  

</faces-config>

4. (Optional)In future posts we will need including local jar files (dependencies) that are not in Maven Central repository. So in the previous WEB-INF folder let's create the folder lib, that will contain these jars. (There are other options to solve this problem, but it is good for me. See Roufid for more accepted solutions)

5. (Optional) Also in a future, we will be using JNDI datasources in Tomcat (and will be referenced in JPA). So we need to create the META-INF folder (in the webapp folder). We will include in this folder the empty file context.xml.


4. Additional files in the src/main/resources folder

(Optional) In a future we will put this files in the src/main resources:

1.  META_INF/persistence.xml (for JPA)
2.  properties/application.properties (for properties files)
3.  bundles/language.properties (for resources bundles)
4.  Other stuff

5. LoginBean.java and test02-login-page.xhtml

1. Let's create the package org.ximodante.jsf.login into src/main/java.
2. Create the java class LoginBean.java 


 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
package org.ximodante.jsf.login;

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

import lombok.Getter;
import lombok.Setter;


@Named
@SessionScoped
public class LoginBean implements Serializable{
 private static final long serialVersionUID = 1L;
 @Getter @Setter private String user;
 @Getter @Setter private String password;
 @Getter private String myError="";
 
 
 public String login () {
  if (user.equalsIgnoreCase("ximo") && password.equals("password")) {
   return "test02-application-page";
  } else {
   myError="Bad User/password";
   return "test02-login-page";
  }
 }

} 

Note:

  • We are using CDI that uses its own annotations. Please do not mix JSF annotation with CDI annotation
  • In CDI all beans should implement Serializable interface or else Tomcat won't start.
  • We are using Lombok annotations @Getter and @Setter.
  • When user is "ximo" and password is "password" we are redirected to the application-page
3. Let's create (optionally) the folder "pages" into the folder "webapp".
4. Let's create the file test02-login-page.xhtml in the folder "pages"


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:p="http://primefaces.org/ui">  
    <h:head>  
    </h:head>  
      
    <h:body>  
      <h:form>  
        <p:panel header="Login Page">    
          <h:outputLabel value="username " />
    <h:inputText value="#{loginBean.user}" />
    <br />
    <h:outputLabel value="password" />
    <h:inputSecret value="#{loginBean.password}"></h:inputSecret>
    <br />
    <h:outputText value="#{loginBean.myError}" />
     </p:panel>
        <p:commandButton value="Login" action="#{loginBean.login}"/>
       </h:form>
    </h:body>  
</html>

5. Let's create a simple application page, to whom we will be redirected when filling the login page. This file is test02-application-page.xhtml and is placed in the same folder "pages"


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:p="http://primefaces.org/ui">  
    <h:head>  
    </h:head>  
      
    <h:body>  
      <h:form>  
        <p:panel header="Application Page (from test02-login-page?)">    
          <h:outputLabel value="This is the application page" />
    
        </p:panel>
        
     </h:form>
   </h:body>  
</html>



6. Project structure

This is the proposed project structure. Take into account that the strictly needed files for this example are displayed in bold style.

Java Resources (src/main/java folder)
  |--src/main/java 
     |--org.ximodante.jsf.login
        |-- LoginBean.java

  |--src/main/resources

     |--META-INF
        |-- persistence.xml
     |--properties
        |--application.properties
     |--bundles
        |--language.properties
     |--other stuff
  
Deployed Resources (src/main folder)
   |--webapp
      |--WEB-INF
         |--beans.xml
         |--faces-config.xml
         |--lib
            |--additional local jars 
      |--pages
         |--test02-login-page.xhtml
         |--test02-application-page.xhtml
      |--META-INF
         |--context.xml
      |--other stuff like css, icons ..
     


7. Executing the page


I if we right-click on test02-login-page.xhtml and select Run As - Run on Server this page will be shown:

If we insert user=ximo and password=password and press Login (button), the application page will be displayed.

We should notice that:

1. LoginBean is a session scoped bean. So its value won't change while the session is active !! Many programmers may not agree with this approach!

2. If we introduce a bad user/password, the attribute "myError" changes its value, but it is not reflected in the form. This will be the subject of a new post.







Comments

Popular posts from this blog

10. JSF How to access my resources files?

Sometimes it is really difficult to access any resources form different Java applications. So let's see some scenarios: 1. Executable jar application in a NO WEB environment. Take into account that this is not a JSF application !!! It is desired to have a property file outside the "jar file" so that we can change properties when needed. For instance, we will place the properties file in the same folder that the "jar file" lies. To access the folder where the jar is, the trick is to access the folder where the compiled classed are placed and scale 3 folders . (Oh! rather strange, if anybody knows a better idea.., he will be welcome). Here is a simple code. The name of the class containing the code is ThisClass, and we have created a Property class that feeds with a file in the same folder that the" jar file" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /** * Gets the folder where resides the executable...

9. JSF: Solving common problems

1. Target Unreachable, identifier [bean] resolved to null When you reference a bean in a xhtml file with "#{bean.method}" and get this error, you should verify that: The bean implements Serializable . The references (javax.servlet-api.4.0.0, javax.faces.2.3.3,  javax.el.api.3.0.1, org.primefaces.6.1) have been selected in your pom.xml You have created the files bean.xml and faces-config.xml in the webapp/WEB-INF folder You have used the correct annotations from CDI  (javax.inject.Named and javax.enterprise.context.SessionScoped, ...) and not ManagedBean or jsf2.2 scopes. 2. Bean declaring a passivating scope must be passivation capable This error causes server not starting and fills up the console with long chained exceptions. It is very annoying. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 SEVERE: A child container failed during start java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to star...