Creare un’applicazione basata su Spring Boot, PrimeFaces e JoinFaces

Tempo fa ho scritto un articolo su come configurare un’applicazione basata su Spring Boot per utilizzare JavaServer Faces e in particolare PrimeFaces: si trattava di un’operazione un po’ ostica che richiedeva l’importazione di alcune librerie e l’utilizzo di opportune configurazioni affinché tutto funzionasse correttamente.

Oggi è disponibile un progetto molto interessante, chiamato JoinFacesche semplifica di molto l’integrazione di Spring Boot con PrimeFaces e con molti altri progetti legati al mondo JavaServer Faces, come per esempio PrimeFaces Extensions, BootsFaces, ButterFaces, RichFaces, OmniFaces e AngularFaces.

In questo articolo descriverò come utilizzare JoinFaces in un’applicazione basata su Spring Boot.

Ricordo brevemente che Spring Boot (http://projects.spring.io/spring-boot/) permette di semplificare di molto lo sviluppo di applicazioni basate sul framework Spring infatti, quando si crea un nuovo progetto basato su Spring, si presentano immediatamente alcuni punti da risolvere: il primo riguarda quali librerie di Spring è necessario importare nel progetto per poter utilizzare le diverse funzionalità offerte dal framework come, per esempio, Spring Data, Spring Integration, Spring Social, ecc. Il secondo punto, strettamente legato al primo, è quali versioni delle librerie devono essere utilizzate. Il terzo aspetto fondamentale da affrontare è la scrittura del codice necessario per effettuare il bootstrap di Spring e l’individuazione e configurazione di tutti i bean che saranno gestiti dal framework e necessari alla nostra applicazione. Tutti questi punti, come vedremo, sono efficacemente risolti dal progetto Spring Boot.

I passi che seguirò in questo articolo sono i seguenti:

  1. Creazione di un progetto basato su Spring Boot
  2. Importazione del progetto in Eclipse
  3. Configurazione del progetto per l’utilizzo di JoinFaces
  4. Aggiunta dei componenti di presentazione (pagine jsf e controller)
  5. Generazione del file .jar e suo utilizzo

Passo 1  – Creazione di un progetto basato su Spring Boot

E’ possibile creare facilmente un’applicazione basata sul progetto Spring Boot utilizzando l’applicazione Spring Initializr presente all’indirizzo https://start.spring.io

Una volta caricata questa pagina nel browser, conviene selezionare il link Switch to the full version, presente in basso alla pagina, per visualizzare la sua versione completa.

Per configurare la nostra applicazione possiamo lasciare i valori di default:

Generate a Maven Project with java and Spring Boot 1.5.4

infatti lo scopo è quello di generare un progetto Maven che utilizza il linguaggio java e la versione di Spring Boot 1.5.4

Si devono poi riempire i campi : Group, Artifact, Name, Description e Package Name con i valori che si preferisce, scegliere il valore Jar per il campo Packaging, perché vogliamo che Maven generi un file .jar che contenga il nostro progetto.

Per questo esempio ho utilizzato i seguenti valori:

Group: com.theserverside
Artifact: demoJoinFaces
Name: demoJoinFaces
Description: Esempio configurazione Spring Boot e JoinFaces
Package Name: com.theserverside.demoJoinFaces

ho lasciato i seguenti valori di default per i seguenti campi:

Packaging: Jar
Java Version: 1.8

Una volta inseriti questi valori è possibile premere bottone verde “Generate Project” per far sì che l’applicazione Spring Initializr prosegua con la creazione del progetto. Il risultato è la generazione di un progetto Maven con i parametri che abbiamo selezionato e il download automatico del file demoJoinFaces.zip: questo file contiene il nostro progetto che possiamo salvare in una directory di appoggio.

Passo 2 – Importazione del progetto in Eclipse

Ora dobbiamo decomprimere il file demoJoinFaces.zip nella directory in cui è stato salvato e poi importare questo progetto in Eclipse.

Per importare il progetto in Eclipse è possibile selezionare la voce di menu File -> Import…, Eclipse visualizza la seguente finestra di dialogo:

ImportEclipse

In questa finestra si deve selezionare il folder Maven e, al suo interno, ‘Existing Maven Projects’ e poi premere ‘Next’, Eclipse visualizza quindi la seguente finestra:

importazione

Selezionando il bottone ‘Browse…’ è possibile scegliere la directory di appoggio in cui abbiamo decompresso i file del progetto e poi premere ‘Finish’ per importare il progetto in Eclipse, come nella seguente figura:

Al termine di questa operazione, Eclipse importerà il nostro progetto che risulterà visibile nella sua finestra Package Explorer, come riportato nella figura seguente:

Il file pom.xml generato è il seguente,

<?xml version="1.0" encoding="UTF-8"?>
<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>com.theserverside</groupId>
	<artifactId>demoJoinFaces</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demoJoinFaces</name>
	<description>Esempio configurazione Spring Boot e JoinFaces</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Se si osservano le righe da 27 a 36, si può notare che durante la generazione del progetto sono stati introdotti due moduli starter, cioè due pacchetti di librerie che Spring Boot mette a disposizione per configurare specifiche funzionalità dell’applicazione, in particolare:

  • spring-boot-starter – per importare le librerie per la configurazione base di spring
  • spring-boot-starter-test – per importare le librerie necessarie per il testing dell’applicazione

Sono proprio questi moduli starter che permettono di semplificare la configurazione delle librerie a cui accennavo all’inizio dell’articolo, con il loro utilizzo non è più necessario elencare tutti i singoli .jar e la loro versione.

Spring Boot mette a disposizione numerosi moduli starter, ciascuno utile per includere nell’applicazione pacchetti di librerie necessarie per implementare specifiche funzionalità; un elenco completo di questi moduli è disponibile all’indirizzo: Spring Boot Reference Guide

Vediamo adesso il contenuto della classe DemoJoinFacesApplication.java:

package com.theserverside.demoJoinFaces;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoJoinFacesApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoJoinFacesApplication.class, args);
	}
}

La classe DemoJoinFacesApplication è stata annotata (riga 6) con @SpringBootApplication: questa annotazione include nella sua definizione le seguenti 3 annotazioni, ciascuna con il seguente significato:

  • @Configuration questa annotazione permette alla classe di definire dei metodi di creazione di bean gestiti da Spring: questo significa che un metodo di questa classe annotato con @Bean restituisce un oggetto che sarà automaticamente gestito dal container di Spring
  • @ComponentScan questa annotazione fa sì che Spring cerchi le classi annotate con @Component, @Service, @Controller@Repository ecc. nel package in cui è definita questa classe, nel nostro caso com.theserverside.demoJoinFaces, e le inserisca nel proprio container
  • @EnableAutoConfiguration questa annotazione abilita il meccanismo di autoconfigurazione che è alla base di Spring Boot: questo meccanismo fa sì che in base alle librerie presenti nel classpath dell’applicazione, cioè quelle dichiarate nel file pom.xml, Spring Boot inserisca automaticamente nel proprio container un insieme di bean, opportunamente configurati, semplificando enormemente la configurazione dell’applicazione.

Sempre nella classe DemoJoinFacesApplication, nel metodo main (righe 9-11), si effettua il bootstrap di Spring Boot passando la classe DemoJoinFacesApplication in input al metodo statico run della classe SpringApplication

Il passo successivo è configurare il progetto in modo da poter utilizzare il progetto JoinFaces

Passo 3 – Configurazione del progetto per l’utilizzo di JoinFaces

Modifichiamo il file pom.xml, presente nella root del progetto, in modo da sostituire l’elemento <parent> e aggiungere l’elemento <dependency> riportati di seguito:

<parent>
    <groupId>org.joinfaces</groupId>
    <artifactId>jsf-spring-boot-parent</artifactId>
    <version>2.4.0</version>
    <relativePath />
</parent>
<dependency>
    <groupId>org.joinfaces</groupId>
    <artifactId>jsf-spring-boot-starter</artifactId>
</dependency>

dopo questa modifica, il contenuto del file pom.xml sarà il seguente:

<?xml version="1.0" encoding="UTF-8"?>
<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>com.theserverside</groupId>
	<artifactId>demoJoinFaces</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demoJoinFaces</name>
	<description>Esempio configurazione Spring Boot e JoinFaces</description>

	<parent>
		<groupId>org.joinfaces</groupId>
		<artifactId>jsf-spring-boot-parent</artifactId>
		<version>2.4.0</version>
		<relativePath />
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.joinfaces</groupId>
			<artifactId>jsf-spring-boot-starter</artifactId>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

In generale, quando si modifica il file pom.xml conviene sempre eseguire il comando Maven Update Project (tasto destro del mouse sul nome del progetto e poi scegliere Maven -> Update Project…) questo per essere sicuri che Eclipse aggiorni le librerie del progetto in base a quanto riportato nel file pom.xml.

Abbiamo terminato la configurazione della nostra applicazione! Il progetto è pronto per ospitare le nostre pagine JSF. Si osservi come l’utilizzo del progetto JoinFaces abbia ridotto la configurazione alla sola modifica del file pom.xml

Passo 4  – Aggiunta dei componenti di presentazione (pagine jsf e controller)

Aggiungiamo alla nostra applicazione una pagina saluti.xhtml che utilizza alcuni tag JSFPrimeFaces in modo da verificare che la configurazione dell’applicazione sia corretta.

Poiché il nostro obiettivo è quello di creare un file jar contenente al suo interno sia la nostra applicazione web, sia il server Tormcat embedded (seguiamo la famosa regola di Spring Boot: “Make jar, not war”) dobbiamo fare attenzione ad inserire le pagine jsf nella seguente directory (e non in una directory WEB-INF come nel caso di file war):

src/main/resources/META-INF/resources

Il progetto che abbiamo generato e importato in eclipse ha soltanto la directory src/main/resources, quindi dobbiamo creare (tasto desto del mouse sulla directory e poi New -> Folder) le due nuove directory META-INF e, al suo interno, resources.

In quest’ultima directory creiamo il nuovo file saluti.xhtml  (tasto desto del mouse sulla directory e poi New -> File)  il cui sorgente è il seguente:

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

<f:view contentType="text/html">
	<h:head />
	<h:body>
		<h:form>
			<p:panel id="panel1" header="DemoJsf">
				<h:outputText value="#{helloController.hello}" />			
				<h:outputText value="Orario: " />
				<h:outputText value="#{helloController.timeStamp}" /><br/><br/>
				<p:commandButton update="panel1" action="#{helloController.updateOrario}" value="Aggiorna orario" />	
			</p:panel>
		</h:form>
	</h:body>
</f:view>
</html>

La pagina saluti.xhtml è quella che vogliamo visualizzare come pagina iniziale del progetto, a tale scopo dobbiamo inserire una classe controller che in corrispondenza dell’url iniziale dell’applicazione (la sua context root) la faccia visualizzare.

Creiamo dunque un nuovo package com.theserverside.demoJoinFaces.controller, per farlo basta cliccare con il tasto destro del mouse sul package com.theserverside.demoJoinFaces e poi scegliere New -> Package e inserire come nome del nuovo package  com.theserverside.demoJoinFaces.controller

In questo nuovo package creiamo una classe controller chiamata HomeController. Per creare la nuova classe basta cliccare con il tasto destro del mouse sul nome del package com.theserverside.demoJoinFaces.controller e scegliere New -> Class 

Il sorgente della classe HomeController è il seguente:

package com.theserverside.demoJoinFaces.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
	
    @RequestMapping("/")
    public String getfirstPage() {
        return "saluti.xhtml";
    }

}

Si osservi l’annotazione @Controller presente alla linea 6: in questo modo si contrassegna la classe HomeController come un componente gestito da Spring, in particolare un componente di tipo controller, cioè un componente che appartiene allo strato di presentazione dell’applicazione (presentation layer) e che è quindi in grado di gestire richieste HTTP provenienti dall’esterno. Al momento dello startup dell’applicazione, Spring crea un’istanza di questa classe e la inserisce nel suo container.

Il metodo  getfirstPage() è invece annotato con @RequestMapping(“/”): questa annotazione fa sì che questo metodo venga invocato ogni volta che l’applicazione riceve una richiesta http GET che abbia come url la sua context root (il nome  dell’applicazione).

Il metodo getfirstPage() non fa nient’altro che restituire il nome della pagina che deve essere visualizzata, quindi invocando nel browser la context root dell’applicazione si ottiene come risultato la visualizzazione della pagina saluti.xhtml

Ritornando alla pagina saluti.xhtml. si può osservare dal suo sorgente che utilizza un ManagedBean HelloController che deve essere creato nel progetto (tasto destro del mouse sul nome del package com.theserverside.demoJoinFaces.controller e poi scegliere New -> Class) e la cui implementazione è la seguente:

package com.theserverside.demoJoinFaces.controller;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="helloController")
@RequestScoped
public class HelloController {
	
        private String timeStamp;
	
	public HelloController() {
		LocalDateTime date = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
		timeStamp = date.format(formatter);
	}
	
	private String hello = "Saluti dall'applicazione demoJoinFaces";

	public String getHello() {
		return hello;
	}

	public void setHello(String hello) {
		this.hello = hello;
	}

	public String getTimeStamp() {
		return timeStamp;
	}

	public void setTimeStamp(String timeStamp) {
		this.timeStamp = timeStamp;
	}

	public String updateOrario() {
		LocalDateTime date = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
		timeStamp = date.format(formatter);
		return null;
	}

}

La classe HelloController inizializza nel costruttore il suo campo timeStamp con la data corrente, per tale campo si utilizza la nuova classe LocalDateTime introdotta in java 8. Inoltre è presente un metodo updateOrario() che permette di aggiornare l’orario ogni volta che questo metodo è invocato.

A questo punto la configurazione del progetto è terminata, nella figura seguente è riportata la sua struttura finale:

Possiamo lanciare l’applicazione cliccando con il tasto destro del mouse sulla classe DemoJoinFacesApplication.java e scegliere la voce di menù Run As -> Java Application

Al termine della fase di avvio, nella finestra Console di Eclipse comparirà il seguente output:

Leggendo le ultime righe è possibile verificare che il web server Tomcat embedded che Spring Boot ha integrato nella nostra applicazione è in ascolto sulla porta 8080, è quindi possibile visualizzare l’applicazione utilizzando l’url:

http://localhost:8080/

Il risultato è il seguente:

La pagina visualizza un semplice tag panel di PrimeFaces con un messaggio di saluto e la data corrente. E’ possibile aggiornare la data visualizzata premendo il bottone “Aggiorna orario”.

Il funzionamento dell’applicazione è molto semplice: quando nel browser si digita l’url http://localhost:8080, il browser invia una richiesta HTTP di tipo GET alla nostra applicazione richiedendo la risorsa “/”. L’uri (Uniform Resource Identifier) richiesta “/” è mappata sul metodo getfirstPage() della classe HomeController tramite l’annotazione @RequestMapping(“/”), quindi Spring invoca il metodo getfirstPage() che restituisce il nome della pagina da visualizzare ed il browser mostra il contenuto di saluti.xhtml

Nella pagina saluti.xhtml sono presenti i seguenti tag jsf che visualizzano il messaggio di saluto con la data e l’ora:

 <h:outputText value="#{helloController.hello}" />         
 <h:outputText value="Orario: " />
 <h:outputText value="#{helloController.timeStamp}" />   

i valori sono letti dai campi hello e timeStamp del managed bean helloController

Nella stessa pagina è anche presente il seguente tag jsf che visualizza un bottone contenente il testo “Aggiorna orario”:

<p:commandButton update="panel1" action="#{helloController.updateOrario}" value="Aggiorna orario" />

La presenza in questo tag dell’attributo action=”#{helloController.updateOrario}” fa sì che quando l’utente preme il bottone “Aggiorna orario”, il framework JSF invoca il metodo updateOrario() della classe HelloController

Il metodo updateOrario()  non fa nient’altro che aggiornare il campo timeStamp e, al termine della sua esecuzione, poiché nell’elemento <p:commandButton> è presente l’attributo update=”panel1″, il framework jsf aggiorna immediatamente il panel con id  panel1 contenente i campi campi hello e timeStamp che quindi risultano aggiornati senza che l’intera pagina debba essere ricaricata. Si osservi come il framework PrimeFaces utilizzi richieste ajax senza che l’utente debba esplicitamente programmarle in Javascript.

 

Passo 5 – Generazione del file .jar e suo utilizzo

Per generare il file .jar contenente la nostra applicazione è possibile cliccare con il tasto destro del mouse sul nome del progetto e scegliere la voce di menù Run As -> Maven build…

Nella finestra che Eclipse visualizza si deve scrivere la stringa package nel campo Goal e poi premere Run, come mostrato nella figura seguente:

generawar1

Eclipse genererà il file demoJoinFaces-0.0.1-SNAPSHOT.jar nella directory target presente all’interno del progetto.

Quello che abbiamo appena generato è un file .jar eseguibile, nel senso che è possibile lanciare l’applicazione con il comando:

java  -jar demoJoinFaces-0.0.1-SNAPSHOT.jar

Il file .jar è eseguibile perché Spring Boot l’ha generato con un server Tomcat embedded al suo interno. L’unico particolare da tener presente è che il server embedded assegna all’applicazione la root context e quindi l’url da utilizzare per visualizzarla è:  http://localhost:8080/ senza inserire il nome dell’applicazione.

Il codice sorgente dell’applicazione è disponibile su GitHub all’indirizzo:

https://github.com/thespringside/demoJoinFaces.git

Nei prossimi articoli continuerò ad approfondire le enormi potenzialità offerte dal framework Spring e dai progetti Spring Boot e Spring Cloud

A presto

@Copyright Roberto Venanzi – www.thespringside.com

Un esempio di web application per la gestione utenti realizzata con Spring Boot, Spring Security, Spring Data JPA e JSF (Parte 1)

In questo articolo descriverò come realizzare una web application che utilizza Spring Security per la gestione dei suoi utenti. L’applicazione permetterà a chiunque di registrarsi scegliendo una username, una password e inserendo la propria email. Nell’applicazione saranno presenti delle pagine pubbliche, visibili a tutti gli utenti, e delle pagine private che saranno accessibili ai soli utenti registrati. L’applicazione potrà essere utilizzata come punto di partenza per la realizzazione di un sistema di gestione delle utenze più complesso.

L’articolo è suddiviso in tre parti: nella prima parte descriverò come installare l’applicazione, come lanciarne l’esecuzione e il suo funzionamento. Nella seconda parte dell’articolo descriverò nel dettaglio la sua implementazione e vedremo come l’utilizzo di Spring Boot e di Spring Security semplificano la scrittura del codice sorgente. Infine, nella terza parte dell’articolo, descriverò come eseguire l’applicazione nel cloud, in particolare descriverò come creare due distinti container Docker, uno contenente la nostra applicazione e l’altro il server MySql e spiegherò come utilizzarli con un provider di servizi cloud.

L’applicazione è basata su Spring Boot e utilizza il progetto Spring Security per le operazioni di autenticazione e autorizzazione, Spring Data JPA per semplificare l’accesso al database e la sua interfaccia utente è realizzata utilizzando PrimeFaces e BootFaces. Le informazioni relative agli utenti registrati sono salvate in un database MySql ma il sistema descritto nell’articolo è del tutto generico e permette di utilizzare un qualunque altro meccanismo di memorizzazione delle utenze.

Il codice sorgente dell’applicazione è presente su GitHub all’indirizzo:

 https://github.com/thespringside/gestioneUtenti.git

Download del progetto

Se sul proprio computer è installato Git è possibile copiare in locale il progetto eseguendo il seguente comando (da una finestra dei comandi di Windows o da una finestra Terminal in Linux):

git clone https://github.com/thespringside/gestioneUtenti.git

questo comando crea una directory gestioneUtenti  e salva al suo interno i file del progetto.

Se non si vuole utilizzare Git è anche possibile effettuare direttamente il download del file .zip contenente l’intero progetto: a tale scopo basta aprire nel browser la pagina del progetto presente su GitHub al seguente indirizzo:

https://github.com/thespringside/gestioneUtenti

in questa pagina è possibile selezionare il bottone ‘Dowload ZIP‘ come evidenziato nella figura seguente:

gitHub

In questo caso il browser scaricherà il file gestioneUtenti-master.zip che dovrà essere decompresso in una directory di appoggio.

Creazione del database

L’applicazione utilizza un database MySql per memorizzare i dati degli utenti (username, password, data creazione, ecc.): è necessario quindi che sia installato in locale un server MySql. Accedendo tramite un qualunque client MySql al server, possiamo creare un database di nome gestioneutenti. Utilizzando, per esempio, la console MySql è possibile utilizzare il seguente comando:

create database gestioneutenti;

si deve poi selezionare il database appena creato tramite il comando:

use gestioneutenti;

e infine creare la seguente tabella utente destinata a contenere le informazioni degli utenti:

CREATE TABLE utente (
   id bigint(20) NOT NULL AUTO_INCREMENT,
   data_creazione datetime,
   email varchar(60),
   password varchar(60),
   role varchar(20),
   username varchar(30),
   PRIMARY KEY (id)
) ENGINE=InnoDB;

 

Esecuzione dell’applicazione

Vediamo ora come eseguire l’applicazione appena scaricata. Ci sono due possibili strade:

  1. esecuzione dell’applicazione tramite Maven
  2. esecuzione dell’applicazione tramite Eclipse

La prima soluzione è la più veloce e permette di lanciare direttamente l’applicazione dalla finestra dei comandi utilizzando il comando mvn del tool Maven, mentre la seconda soluzione prevede che il progetto sia prima importato in Eclipse e poi che l’applicazione sia compilata ed eseguita all’interno dell’IDE.

1- esecuzione dell’applicazione tramite Maven

Se si ha Maven installato sul proprio computer, una volta effettuato il download del progetto è possibile spostarsi all’interno della directory in cui è stata salvata l’applicazione e lanciarla tramite il seguente comando:

mvn spring-boot:run

Al termine della fase di inizializzazione, l’applicazione sarà disponibile al seguente indirizzo:

http://localhost:8080/

2 – esecuzione dell’applicazione tramite Eclipse

Per semplificare lo sviluppo dell’applicazione ho utilizzato il progetto Lombok. Questo progetto permette di semplificare la scrittura delle classi java tramite l’utilizzo di apposite annotazioni che consentono di evitare di scrivere i metodi getter e settertoString e, soprattutto, i metodi equalshashCode che assumono un ruolo particolarmente importante quando si utilizza un framework come JPA (Java Persistence API).

Per poter utilizzare Lombok in Eclipse è necessario prima installarlo: a tale scopo basta effettuare il download del file lombok.jar ed eseguire il comando:

java -jar lombok.jar

Questo comando lancia l’installer di Lombok che tenta di determinare i diversi IDE installati sul computer, in ogni caso è sempre possibile premere il bottone ‘Specify location…‘ per scegliere manualmente il percorso in cui è installato Eclipse sul proprio file system, come evidenziato nella figura seguente:

lombok

Dopo aver correttamente installato il progetto Lombok è possibile lanciare Eclipse ed importare il progetto GestioneUtenti precedentemente scaricato da GitHub: a tale scopo si deve selezionare la voce di menù File -> Import… e poi scegliere l’opzione Maven -> Existing Maven Projects, in questo modo Eclipse visualizzerà una finestra di dialogo in cui sarà possibile scegliere la directory in cui è stato precedentemente salvato il progetto GestioneUtenti sul proprio file system. La procedura da seguire è del tutto analoga a quella descritta nell’articolo http://www.thespringside.com/?p=19 dove ho spiegato come importare un progetto Maven generato dal tool Spring Initializr

Al termine dell’importazione è importante cliccare con il tasto destro del mouse sul nome del progetto e scegliere la voce Maven -> Update Project… per permettere ad Eclipse di importare tutte le librerie necessarie al progetto (ricordo che i file .jar utilizzati dall’applicazione sono dichiarati nel file pom.xml). Per eseguire l’applicazione basterà poi premere con il tasto destro del mouse sul nome del file GestioneUtentiApplication.java (presente nella directory src/main/java e appartenente al package com.thespringside.gestioneutenti)  e scegliere  Run As -> Java Application

Terminata la fase di avvio dell’applicazione è possibile visualizzare la sua home page all’indirizzo http://localhost:8080/

Descrizione dell’applicazione

Qualunque sia il metodo seguito per lanciare l’applicazione, la prima pagina visualizzata quando si inserisce nel browser l’indirizzo:  http://localhost:8080/ è la seguente:

 

home

Nell’applicazione ci sono alcune pagine pubbliche e alcune pagine private. Le pagine pubbliche, come la home page, sono accessibili da chiunque, mentre le pagine private possono essere visualizzate solo da utenti che siano registrati nel sistema e dopo che abbiano correttamente effettuato l’operazione di login.

Selezionando il bottone ‘Registrati‘ è possibile effettuare la registrazione di un nuovo utente. L’applicazione visualizza la seguente pagina:

registrazione1

In questa pagina è necessario immettere le seguenti informazioni:

  • username
  • password
  • ripetizione della password immessa
  • e-mail

Si osservi che una volta immessa la username, non appena il campo perde il focus, scatta un evento di validazione per verificare che il valore immesso non sia già utilizzato da un altro utente; in questo caso l’applicazione segnala l’errore come visualizzato nella figura seguente:

erroreUsername

Altre validazioni sono effettuate sui restanti campi. Per esempio, se l’indirizzo e-mail non ha un formato corretto, l’applicazione visualizza il seguente messaggio di errore:

erroreEmail

Se non sono riscontrati errori, dopo la pressione del bottone ‘Registra utente‘, l’applicazione salva le informazioni del nuovo utente nel database e visualizza un messaggio per confermare la sua corretta registrazione:

fineRegistrazione

A questo punto abbiamo un utente registrato nell’applicazione che, quindi, potrà accedere alle pagine protette. Per esempio potrà visualizzare la lista degli utenti registrati nel sistema scegliendo la voce di menù Utenti -> Lista Utenti, come evidenziato nella figura seguente:

menuListaUtenti

Avendo richiesto la visualizzazione di una pagina riservata ai soli utenti registrati, l’applicazione mostra la pagina di login per permettere all’utente di inserire la sua username e password:

login

Una volta immessi la username e la password e premuto il bottone ‘Login‘, l’applicazione verifica che le informazioni immesse si riferiscono ad un utente registrato e, in caso affermativo, visualizza la pagina protetta contenete la lista di tutti gli utenti registrati nel sistema:

listaUtenti

Questa pagina visualizza la lista degli utenti che si sono registrati e, per ciascun utente, la sua username, l’email, la data di creazione e il ruolo assegnato. Ovviamente non è visualizzata la password che l’applicazione salva nel database non in chiaro ma cifrata tramite l’utilizzo dell’algoritmo Bcrypt. L’applicazione assegna in automatico, a ciascun utente, un ruolo chiamato ROLE_USER; l’applicazione è anche predisposta per utilizzare un secondo ruolo chiamato ROLE_ADMIN; questi ruoli non sono attualmente utilizzati ma sono stati introdotti per mostrare come definire i ruoli e come assegnarli ad un utente. Successive estensioni dell’applicazione potrebbero differenziare gli utenti in base ai ruoli assegnati e permettere ad utenti con ruoli diversi di poter accedere a differenti funzionalità.

Sempre nella pagina contenente la lista degli utenti è presente, in alto a destra, il nome dell’utente attualmente connesso e il bottone per effettuare l’operazione di logout, questa operazione è utile se, per esempio, l’utente vuole disconnettersi per poi effettuare il login utilizzando una username diversa.

Per finire, un’ultima osservazione: per realizzare l’applicazione ho utilizzato il progetto BootsFaces che permette facilmente di integrare il famoso framework Bootstrap in applicazioni che utilizzano JavaServer Faces. In questo modo è facile realizzare applicazioni web responsive che utilizzano i componenti e i widget di Bootstrap. Se si visualizza l’applicazione Gestione Utenti in un browser di un dispositivo mobile, si ottiene la seguente visualizzazione che si adatta alle dimensioni del device:

homeMobile

mentre la pagina di registrazione degli utenti sarà visualizzata nel seguente modo:

registrazioneMobile

Nella seconda parte di questo articolo descriverò nel dettaglio l’implementazione di questa applicazione.

A presto

@Copyright Roberto Venanzi – www.thespringside.com

Creare un’applicazione basata su Spring Boot, JSF (JavaServer Faces) e PrimeFaces

In questo articolo descriverò come creare un’applicazione basata su Spring Boot, JSF (JavaServer Faces) e PrimeFaces. L’esempio che vedremo utilizzerà una piccola variante rispetto alla configurazione standard di una web application basata su Spring Boot, questa variante è necessaria per la corretta integrazione dei diversi framework adottati.

Iniziamo con una brevissima introduzione su Spring Boot, rimandando ai prossimi articoli l’approfondimento delle sue caratteristiche.

Il progetto Spring Boot (http://projects.spring.io/spring-boot/) permette di semplificare, e di molto, lo sviluppo di applicazioni basate sul framework Spring. Quando si crea un nuovo progetto basato su Spring, si presentano immediatamente alcuni punti da risolvere: il primo riguarda quali librerie di Spring è necessario importare nel progetto per poter utilizzare le diverse funzionalità offerte dal framework come, per esempio, Spring Data, Spring Integration, Spring Social, ecc Il secondo punto, strettamente legato al primo, è quali versioni delle librerie devono essere utilizzate. Il terzo aspetto fondamentale da affrontare è la scrittura del codice necessario per effettuare il bootstrap di Spring e l’individuazione e configurazione di tutti i bean che saranno gestiti dal framework e necessari alla nostra applicazione. Tutti questi punti, come vedremo, sono efficacemente risolti dal progetto Spring Boot.

I passi che seguirò in questo articolo sono i seguenti:

  1. Creazione di un progetto basato su Spring Boot
  2. Importazione del progetto in Eclipse
  3. Configurazione del progetto per l’utilizzo di JavaServer Faces e PrimeFaces
  4. Generazione del file .war e suo utilizzo

Passo 1  – Creazione di un progetto basato su Spring Boot

E’ possibile creare facilmente un’applicazione basata sul progetto Spring Boot utilizzando l’applicazione Spring Initializr presente all’indirizzo https://start.spring.io

starter

Una volta caricata questa pagina nel browser, conviene selezionare il link Switch to the full version, presente in basso alla pagina, per visualizzare la sua versione completa.

Per configurare la nostra applicazione possiamo lasciare i valori di default:

Generate a Maven Project with Spring Boot 1.2.7

infatti lo scopo è quello di generare un progetto Maven con la versione di Spring Boot 1.2.7

Si devono poi riempire i campi : Group, Artifact, Name, Description e Package Name con i valori che si preferisce, scegliere il valore War per il campo Packaging, perché vogliamo che Maven generi un file .war, cioè una web application che contenga il nostro progetto.

Per questo esempio ho utilizzato i seguenti valori:

Group: com.theserverside
Artifact: demoJsf
Name: demoJsf
Description: Esempio configurazione Spring Boot, JSF e PrimeFaces
Package Name: com.theserverside.demoJsf
Packaging: War

ho lasciato i seguenti valori di default per i seguenti campi:

Java Version: 1.8
Language: Java

Una volta inseriti questi valori è possibile premere bottone verde “Generate Project” per far sì che l’applicazione Spring Initializr prosegua con la creazione del progetto. Il risultato è la generazione di un progetto Maven con i parametri che abbiamo selezionato e il download automatico del file demoJsf.zip: questo file contiene il nostro progetto che possiamo salvare in una directory di appoggio.

Passo 2 – Importazione del progetto in Eclipse

Ora dobbiamo decomprimere il file demoJsf.zip nella directory in cui è stato salvato e poi importare questo progetto in Eclipse.

Per importare il progetto in Eclipse è possibile selezionare la voce di menu File -> Import…, Eclipse visualizza la seguente finestra di dialogo:

ImportEclipse

In questa finestra si deve selezionare il folder Maven e, al suo interno, ‘Existing Maven Projects’ e poi premere ‘Next’, Eclipse visualizza quindi la seguente finestra:

importazione

Selezionando il bottone ‘Browse…’ è possibile scegliere la directory di appoggio in cui abbiamo decompresso i file del progetto e poi premere ‘Finish’ per importare il progetto in Eclipse, come nella seguente figura:

ImportEclipse2

Al termine di questa operazione, Eclipse importerà il nostro progetto che risulterà visibile nella sua finestra Package Explorer, come riportato nella figura seguente:

struttura

Il file pom.xml generato è il seguente,


<?xml version="1.0" encoding="UTF-8"?>
<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>com.theserverside</groupId>
  <artifactId>demoJsf</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>demoJsf</name>
  <description>
        Esempio configurazione Spring Boot, JSF e PrimeFaces
  </description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

  </dependencies>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  

</project>

Se si osservano le righe da 30 a 39, si può notare che durante la generazione del progetto sono stati introdotti due moduli starter, cioè due pacchetti di librerie che Spring Boot mette a disposizione per configurare specifiche funzionalità dell’applicazione, in particolare:

  • spring-boot-starter-web – per importare le librerie necessarie per una web application
  • spring-boot-starter-tomcat – per importare le librerie necessarie per l’utilizzo del server Tomcat embedded

Sono proprio questi moduli starter che permettono di semplificare la configurazione delle librerie a cui accennavo all’inizio dell’articolo, con il loro utilizzo non è più necessario elencare tutti i singoli .jar e la loro versione.

Spring Boot mette a disposizione numerosi moduli starter, ciascuno utile per includere nell’applicazione pacchetti di librerie necessarie per implementare specifiche funzionalità; un elenco completo dei moduli starter è disponibile all’indirizzo: Spring Boot Reference Guide

Vediamo adesso il contenuto della classe DemoJsfApplication.java:

package com.theserverside.demoJsf;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoJsfApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoJsfApplication.class, args);
    }
}

La classe DemoJsfApplication è stata annotata (riga 6) con @SpringBootApplication: questa annotazione include nella sua definizione le seguenti 3 annotazioni, ciascuna con il seguente significato:

  • @Configuration questa annotazione permette alla classe di definire dei metodi di creazione di bean gestiti da Spring: questo significa che un metodo di questa classe annotato con @Bean restituisce un oggetto che sarà automaticamente gestito dal container di Spring
  • @ComponentScan questa annotazione fa sì che Spring cerchi le classi annotate con @Component, @Service, @Controller@Repository ecc. nel package in cui è definita questa classe, nel nostro caso com.theserverside.demoJsf, e le inserisca nel proprio container
  • @EnableAutoConfiguration questa annotazione abilita il meccanismo di autoconfigurazione che è alla base di Spring Boot: questo meccanismo fa sì che in base alle librerie presenti nel classpath dell’applicazione, cioè quelle dichiarate nel file pom.xml, Spring Boot inserisca automaticamente nel proprio container un insieme di bean, opportunamente configurati, semplificando enormemente la configurazione dell’applicazione.

Sempre nella classe DemoJsfApplication, nel metodo main (righe 9-11), si effettua il bootstrap di Spring Boot passando la classe DemoJsfApplication in input al metodo run di SpringApplication

Per verificare che l’importazione sia andata a buon fine è possibile eseguire l’applicazione cliccando con il tasto destro del mouse sul nome della classe DemoJsfApplication.java e scegliere Run As -> Java Application. Si osservi che, pur trattandosi di una web application, è possibile eseguirla come un’applicazione stand-alone, grazie alla presenza del server Tomcat embedded che Spring Boot inserisce nella nostra applicazione.

Al termine della fase di avvio, nella finestra Console di Eclipse, possiamo verificare che è stato lanciato il web server Tomcat incluso nell’applicazione e che la nostra applicazione è configurata sulla porta 8080:

run1

E’ possibile testare il corretto funzionamento dell’applicazione utilizzando l’url: http://localhost:8080/, la pagina visualizzata sarà la seguente:

primorun

Come si può osservare, l’applicazione funziona correttamente ma restituisce una pagina di errore 404- Not Found: questo perché non abbiamo impostato una pagina iniziale.

Si osservi che nell’url manca l’application context (il nome dell’applicazione), questo accade perché l’applicazione utilizza il server Tomcat embedded che utilizza la context di ROOT

Ricapitoliamo quanto fatto fino ad ora: abbiamo creato un progetto basato su Spring Boot, l’abbiamo importato in Eclipse e, infine, l’abbiamo eseguito per verificare che non si siano verificati errori. Il passo successivo è configurare il progetto in modo da poter utilizzare JavaServer FacesPrimeFaces

Passo 3 – Configurazione del progetto per l’utilizzo di JavaServer Faces e PrimeFaces

Modifichiamo il file pom.xml, presente nella root del progetto, in modo da aggiungere le seguenti librerie:

  
<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>
    
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
</dependency>

<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-api</artifactId>
  <version>2.2.7</version>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-impl</artifactId>
  <version>2.2.7</version>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>org.primefaces</groupId>
  <artifactId>primefaces</artifactId>
  <version>5.2</version>
</dependency>

dopo questa modifica, il contenuto del file pom.xml sarà il seguente:

<?xml version="1.0" encoding="UTF-8"?>
<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>com.thespringside</groupId>
  <artifactId>demoJsf</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>demoJsf</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.7.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>
    
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
    </dependency>
    
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.2.7</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.2.7</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>5.2</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

Eliminiamo, nel package com.theserverside.demoJsf, la classe ServletInitializer.java che è stata introdotta durante la generazione del progetto.

Modifichiamo la classe DemoJsfApplication  in modo da farle estendere la classe SpringBootServletInitializer e aggiungiamo le righe da 23 a 41 evidenziate nella figura seguente:

package com.thespringside.demoJsf;

import javax.faces.application.Application;
import javax.faces.webapp.FacesServlet;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;

import com.sun.faces.config.ConfigureListener;

@SpringBootApplication
public class DemoJsfApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(DemoJsfApplication.class, args);
    }
    
    @Override
    protected SpringApplicationBuilder 
        configure(SpringApplicationBuilder application) {
            return application.sources(DemoJsfApplication.class);
    }
    
    @Bean
    public FacesServlet facesServlet() {
        return new FacesServlet();
    }
    

    @Bean
    public ServletRegistrationBean facesServletRegistration() {
      ServletRegistrationBean registration = 
          new ServletRegistrationBean(facesServlet(), "*.xhtml");
      registration.setName("FacesServlet");
      return registration;
    }
  
}

Il primo metodo configure(SpringApplicationBuilder application), di cui effettuiamo l’override (per questo abbiamo esteso la classe SpringBootServletInitializer), permette di effettuare il bootstrap di Spring Boot quando l’applicazione è utilizzata con un web server esterno.

Il secondo metodo facesServlet() permette di creare la servlet FacesServlet che gestisce le pagine JavaServer Faces

Il terzo metodo permette di registrare nella nostra applicazione la servlet FacesServlet e di configurarla in modo da farle gestire le pagine JSF aventi l’estensione .xhtml

A questo punto dobbiamo creare la directory WEB-INF all’interno della directory src/main/webapp, per farlo basta cliccare con il tasto destro del mouse sulla directory webapp, scegliere new -> Folder nel menù contestuale che è visualizzato, e assegnare il nome WEB-INF alla nuova directory creata

In questa nuova directory WEB-INF creiamo i due nuovi file web.xml e faces-config.xml, il cui contenuto è il seguente:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>    
</web-app>

Nel file web.xml è stata definita la servlet FacesServlet che permette di gestire le pagine JSF: potrebbe sembrare ridondante dover definire nuovamente questa servlet, si ricordi infatti che l’abbiamo già definita nella classe DemoJsfApplication.java, il problema è che, senza ripetere questa definizione nel file web.xml, Tomcat va in errore e non riesce ad utilizzare JavaServer Faces e PrimeFaces

<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">
  
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>
 
</faces-config>

Nel file faces-config.xml è stato dichiarato l’elemento SpringBeanFacesELResolver che permette alle pagine JSF e ai suoi Managed Bean di avere accesso, tramite l’utilizzo dell’expression language, ai bean gestiti dal container di Spring (Spring Bean): è in questo modo che è possibile integrare i framework JavaServer Faces e Spring.

Come ultimo passo aggiungiamo alla nostra applicazione, nella directory webapp, una pagina html index.html e un’altra pagina saluti.xhtml che utilizza alcuni tag JSFPrimeFaces in modo da verificare che la configurazione dell’applicazione sia funzionante.

<!DOCTYPE html>
<html>
  <head>
    <title>Titolo pagina</title>
  </head>
  <body>
    Saluti dall'applicazione DemoJsf!!! 
  </body>
</html> 

 
<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">
  <f:view contentType="text/html">
    <h:head />
      <h:body>
        <p:panel id="panel1" header="DemoJsf">
          <h:outputText value="Saluti dall'applicazione DemoJsf" />
        </p:panel>
      </h:body>
  </f:view>
</html>

A questo punto la configurazione del progetto è terminata, nella figura seguente è riportata la sua struttura finale:

struttura

Possiamo lanciare l’applicazione cliccando con il tasto destro del mouse sulla classe DemoJsFApplicaztion.java e scegliere la voce di menù Run As -> Java Application

Al termine della fase di avvio, nella finestra Console di Eclipse comparirà il seguente output:

run2

Leggendo le ultime righe è possibile verificare che il web server Tomcat embedded che Spring Boot ha integrato nella nostra applicazione è in ascolto sulla porta 8080, è quindi possibile visualizzare l’applicazione utilizzando l’url:

http://localhost:8080/saluti.xhtml

Il risultato è il seguente:

paginafinale

la pagina visualizza un semplice tag panel di PrimeFaces con un messaggio di saluto.

Passo 4 – Generazione del file .war e suo utilizzo

Per generare il file .war contenente la nostra applicazione è possible cliccare con il tasto destro del mouse sul nome del progetto e scegliere la voce di menù Run As -> Maven build…

Nella finestra che Eclipse visualizza si deve scrivere la stringa package nel campo Goal e poi premere Run, come mostrato nella figura seguente:

 generawar1

Eclipse genererà il file demoJsf-0.0.1-SNAPSHOT.war nella directory target presente all’interno del progetto.

Quello che abbiamo appena generato è un file .war eseguibile, nel senso che è possibile lanciare l’applicazione con il comando:

java  -jar  demoJsf-0.0.1-SNAPSHOT.war

Il file .war è eseguibile perché Spring Boot l’ha generato con un server Tomcat embedded al suo interno. L’unico particolare da tener presente è che il server embedded assegna all’applicazione la context di ROOT e quindi l’url da utilizzare è:  http://localhost:8080/ senza inserire il nome dell’applicazione.

Lo stesso file può essere utilizzato, senza nessuna modifica, con un server Tomcat esterno: basta copiarlo nella sua directoty webapps. In questo caso, per accedere all’applicazione si dovrà utilizzare, come context dell’applicazione, il nome del suo file .war, quindi l’url sarà: http://localhost:8080/demoJsf-0.0.1-SNAPSHOT/

Alla base di questo duplice comportamento del file .war, cioè come un’applicazione stand-alone eseguibile oppure come una web application da deploiare in un web server esterno, c’è il plugin Spring Maven Boot Plugin che è stato configurato nel file pom.xml del progetto:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

Questo plugin, durante la fase di creazione del file .war, verifica se le librerie relative al server Tomcat configurate nel file pom.xml hanno come scope il valore provided e, in caso affermativo, le copia in una directory di nome lib-provided presente all’interno del file .war stesso. E’ proprio per questo motivo che sono stati aggiunti i seguenti elementi nel file pom.xml:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <scope>provided</scope>
</dependency>
    
<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>

Lo stesso plugin rende anche eseguibile il file .war inserendo nel suo file MANIFEST.MF l’attributo:

Start-Class: com.thespringside.demoJsf.DemoJsfApplication

cioè il nome completo della classe contenente il metodo main. In questo modo, eseguendo il file .war tramite il comando  java -jar, viene invocato il metodo main che a sua volta effettua lo startup di Spring Boot.

Il file .war è poi utilizzabile anche con un server Tomcat esterno grazie al fatto che la classe java DemoJsfApplication estende la classe SpringBootServletInitializer ed effettua l’override del metodo configure. In fase di avvio dell’applicazione, il web server invoca questo metodo configure il quale, a sua volta, effettua lo startup di Spring Boot

Il codice sorgente dell’applicazione è disponibile su GitHub all’indirizzo:

https://github.com/thespringside/demoJsf.git

Nei prossimi articoli continuerò ad approfondire le enormi potenzialità offerte dal framework Spring e dal progetto Spring Boot

A presto

@Copyright Roberto Venanzi – www.thespringside.com