4. Utilizzo dell’applicazione
Ora desideriamo mettere in funzione l'applicazione al di fuori di IDE, STS (per il server) e Webstorm (per il client).
4.1. Distribuzione del servizio web su un server Tomcat
Abbiamo visto nel paragrafo 2.11.9 come creare un archivio WAR per Tomcat. Ripetiamo qui l’operazione. Innanzitutto, per preservare l’esistente, duplichiamo il progetto Eclipse [rdvmedecins-webapi-v3] in [rdvmedecins-webapi-v4].
![]() |
Il file [pom.xml] viene modificato come segue:
<modelVersion>4.0.0</modelVersion>
<groupId>istia.st.spring4.mvc</groupId>
<artifactId>rdvmedecins-webapi-v4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>rdvmedecins-webapi-v3</name>
<description>Gestion de RV Médecins</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>istia.st.spring4.rdvmedecins</groupId>
<artifactId>rdvmedecins-metier-dao-v2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
Le modifiche devono essere apportate in due punti:
- riga 5: occorre specificare che verrà generato un archivio WAR (Web ARchive);
- righe 23-27: occorre aggiungere una dipendenza dall’artefatto [spring-boot-starter-tomcat]. Questo artefatto include tutte le classi di Tomcat nelle dipendenze del progetto;
- riga 26: questo artefatto è [provided], ovvero gli archivi corrispondenti non saranno inseriti nel WAR generato. Infatti, tali archivi si troveranno sul server Tomcat su cui verrà eseguita l’applicazione;
È inoltre necessario configurare l’applicazione web. In assenza del file [web.xml], ciò avviene tramite una classe che eredita da [SpringBootServletInitializer]:
![]() |
La classe [ApplicationInitializer] è la seguente:
package rdvmedecins.web.config;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ApplicationInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
}
- riga 6: la classe [ApplicationInitializer] estende la classe [SpringBootServletInitializer];
- riga 8: il metodo [configure] viene ridefinito (riga 7);
- riga 9: viene fornita la classe [AppConfig] che configura il progetto;
Fatto ciò, potrebbe essere necessario aggiornare il progetto Maven (io ho dovuto farlo): [clic droit sur projet / Maven / Update project] o [Alt-F5].
Per eseguire il progetto, si può procedere come segue:
![]() |
- in [1], si esegue il progetto su uno dei server registrati in IDE Eclipse;
- in [2], si seleziona [tc Server Developer], che è presente per impostazione predefinita. Si tratta di una variante di Tomcat;
Si ottiene il seguente risultato:
![]() |
È normale. Ricordiamo che il servizio web non ha URL né [/] tra i propri metodi. Quando si provano URL e [/getAllMedecins], si ottiene la seguente risposta:
![]() |
È normale. Il servizio web è protetto.
Ora avviamo il client [rdvmedecins-angular-v2] in WebStorm:
![]() |
In [1], inseriamo l’URL del nuovo servizio web [http://localhost:8080/rdvmedecins-webapi-v4]. Si ottiene il seguente risultato:

Per eseguire l'applicazione al di fuori di IDE STS, esistono diverse soluzioni. Eccone una.
Scaricare una versione di Tomcat [http://tomcat.apache.org/download-80.cgi] (luglio 2014):
![]() |
Si seleziona in [1] una versione compressa in formato ZIP, che viene decompressa in [2]. Si torna a STS:
![]() |
- nella scheda [Servers], si fa clic con il tasto destro sull'applicazione [rdvmedecins-webapi-v4] e si seleziona l'opzione [Browse Deployment Location];
- in [4]: copiare la cartella [rdvmedecins-webapi-v4];
![]() |
- in [5], incollare la cartella [rdvmedecins-webapi-v4] nella cartella [webapps] di Tomcat;
- in [6], si esegue il file di comando [startup.bat] (il server Tomcat integrato in STS deve essere arrestato). Si apre una finestra DOS per visualizzare i log di Tomcat. Questi devono indicare che l'applicazione [rdvmedecins-webapi-v4] è stata avviata.
Per verificarlo, si esegue nuovamente il client Angular [rdvmedecins-angular-v2] in Webstorm:
![]() |
In [1], si inserisce l'URL del nuovo servizio web [http://localhost:8080/rdvmedecins-webapi-v4]. Si ottiene il seguente risultato:

4.2. Distribuzione del client Angular sul server Tomcat
Ora che il servizio web è stato distribuito su Tomcat, procederemo alla distribuzione del client Angular su un server. Può benissimo trattarsi dello stesso server che ospita già il servizio web. Seguiremo questa procedura.
Per prima cosa duplichiamo il client [rdvmedecins-angular-v2] in [rdvmedecins-angular-v3] e apportiamo le seguenti modifiche:
![]() |
- in [1], tutto è stato spostato in una cartella [app] ;
- in [1], è stata eliminata la cartella [bower-components] che conteneva le varie librerie CSS e JS necessarie al progetto. Tutti questi elementi sono stati copiati nella cartella [lib] [2];
- in [1], il file [app.html] è stato rinominato [index.html];
Il file [index.html] è stato modificato per tenere conto delle modifiche ai percorsi delle risorse utilizzate:
<!DOCTYPE html>
<html ng-app="rdvmedecins">
<head>
<title>RdvMedecins</title>
...
<!-- il CSS -->
...
<link href="lib/bootstrap-theme.min.css" rel="stylesheet"/>
<link href="lib/bootstrap-select.min.css" rel="stylesheet"/>
</head>
<!-- controller [appCtrl], modello [app] -->
<body ng-controller="appCtrl">
<div class="container">
...
</div>
<!-- Bootstrap core JavaScript ================================================== -->
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/bootstrap-select.min.js"></script>
<script type="text/javascript" src="lib/footable.js"></script>
<!-- AngularJS -->
<script type="text/javascript" src="lib/angular.min.js"></script>
<script type="text/javascript" src="lib/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="lib/angular-route.min.js"></script>
<script type="text/javascript" src="lib/angular-translate.min.js"></script>
<script type="text/javascript" src="lib/angular-base64.min.js"></script>
<!-- moduli -->
...
<!-- servizi -->
...
<!-- direttive -->
...
<!-- controller -->
....
</body>
</html>
Inoltre, il controller [loginCtrl] è stato modificato per puntare al server corretto, in modo da evitare che l'utente debba digitare il proprio URL:
// credenziali
app.serverUrl = "http://localhost:8080/rdvmedecins-webapi-v4";
app.username = "admin";
app.password = "admin";
Fatto ciò, eseguiamo il file [index.html]:
![]() | ![]() |
Quindi accediamo al servizio web. Dovrebbe funzionare. Una volta verificato ciò, arrestiamo il server Tomcat. Riutilizzeremo il server integrato di STS.
In STS, copiamo tutto il contenuto della cartella [rdvmedecins-angular-v3/app] nella cartella [webapp] del progetto [rdvmedecins-webapi-v4] (scheda Navigator) [1]:
![]() |
Fatto ciò, avviamo [2], il server VMware di STS, quindi richiediamo URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:
![]() |
C'è un problema di autorizzazioni in [3]. Non c'è da stupirsi, dato che abbiamo protetto il servizio web. Dobbiamo specificare che l'accesso al file [/app/index.html] è libero. Torniamo in Eclipse:
![]() |
Ricordiamo che i diritti di accesso sono stati dichiarati nella classe [SecurityConfig]. Modifichiamola come segue:
@Override
protected void configure(HttpSecurity http) throws Exception {
// CSRF
http.csrf().disable();
// la password viene trasmessa tramite l'intestazione Authorization: Basic xxxx
http.httpBasic();
// il metodo HTTP OPTIONS deve essere autorizzato per tutti
http.authorizeRequests() //
.antMatchers(HttpMethod.OPTIONS, "/", "/**").permitAll();
// la cartella [app] è accessibile a tutti
http.authorizeRequests() //
.antMatchers(HttpMethod.GET, "/app", "/app/**").permitAll();
// solo il ruolo ADMIN può utilizzare l'applicazione
http.authorizeRequests() //
.antMatchers("/", "/**") // tutte le URL
.hasRole("ADMIN");
}
- righe 11-12: si autorizza chiunque a leggere la cartella [app] e il suo contenuto. Per farlo, ci si ispira alle righe precedenti.
Ora riavviamo il server Tomcat di STS, quindi richiediamo nuovamente URL e [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:

Questa volta funziona.
4.3. Le intestazioni CORS
Forse ricorderete che abbiamo faticato non poco per gestire le intestazioni CORS. Nell’esempio precedente:
- il servizio web si trova all'indirizzo URL [http://localhost:8080/rdvmedecins-webapi-v4];
- il client HTML si trova su URL [http://localhost:8080/rdvmedecins-webapi-v4/app];
Il client HTML e il servizio web si trovano quindi sullo stesso server [http://localhost:8080]. Non vi sono quindi conflitti CORS, poiché questi si verificano solo quando il client e il server non si trovano nello stesso dominio. Dovremmo poterlo verificare. Torniamo a STS:
![]() |
La generazione o meno delle intestazioni CORS è controllata da un valore booleano definito nella classe [ApplicationModel]:
// dati di configurazione
private boolean CORSneeded = true;
Impostiamo il valore booleano sopra indicato su false, riavviamo il servizio web e richiediamo nuovamente il codice URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]. Si constata che l'applicazione funziona.
4.4. Distribuzione del client Angular su un tablet Android
Lo strumento [Phonegap] [http://phonegap.com/] consente di generare un eseguibile per dispositivi mobili (Android, IoS, Windows 8, ...) a partire da un'applicazione HTML / JS / CSS. Esistono diversi modi per raggiungere questo obiettivo. Noi utilizziamo il più semplice: uno strumento disponibile online sul sito di Phonegap [http://build.phonegap.com/apps].
![]() |
- prima di [1], potrebbe essere necessario creare un account;
- in [1], si inizia;
- in [2], si sceglie un piano gratuito che consente di creare una sola applicazione Phonegap;
![]() |
- in [3], si scarica l'applicazione compressa [4] (la cartella [app] creata al paragrafo 4.2 è compressa);
![]() |
- in [5], si assegna un nome all'applicazione;
- in [6], si procede alla compilazione. Questa operazione può richiedere 1 minuto. Attendere fino a quando le icone delle diverse piattaforme mobili indicano che la compilazione è terminata;
![]() |
- sono stati generati solo i file binari per Android ([7]) e Windows ([8]);
- fare clic su [7] per scaricare il file binario Android;
![]() |
- in [9] il file binario [apk] scaricato;
Avviare un emulatore [GenyMotion] per un tablet Android (vedere paragrafo 6.4):
![]() |
Nell'immagine sopra, si avvia un emulatore di tablet con Android API 16. Una volta avviato l'emulatore,
- sbloccarlo trascinando il cursore di sblocco (se presente) sul lato e poi rilasciandolo;
- con il mouse, trascinate il file [PGBuildApp-debug.apk] che avete scaricato e rilasciatelo sull'emulatore. Verrà quindi installato ed eseguito;
![]() |
È necessario sostituire URL con [1]. A tal fine, in una finestra di comando, digitate il comando [ipconfig] (riga 1 qui sotto) che visualizzerà i diversi indirizzi IP del vostro computer:
C:\Users\Serge Tahé>ipconfig
Configuration IP de Windows
Carte réseau sans fil Connexion au réseau local* 15 :
Statut du média. . . . . . . . . . . . : Média déconnecté
Suffixe DNS propre à la connexion. . . :
Carte Ethernet Connexion au réseau local :
Suffixe DNS propre à la connexion. . . : ad.univ-angers.fr
Adresse IPv6 de liaison locale. . . . .: fe80::698b:455a:925:6b13%4
Adresse IPv4. . . . . . . . . . . . . .: 172.19.81.34
Masque de sous-réseau. . . . . . . . . : 255.255.0.0
Passerelle par défaut. . . . . . . . . : 172.19.0.254
Carte réseau sans fil Wi-Fi :
Statut du média. . . . . . . . . . . . : Média déconnecté
Suffixe DNS propre à la connexion. . . :
...
Annotate l’indirizzo Wi-Fi IP (righe 6-9) oppure l’indirizzo sulla rete locale IP (righe 11-17). Quindi utilizzare questo indirizzo IP nel campo URL del server web:
![]() |
Fatto ciò, connettiti al servizio web:
![]() |
Provate l’applicazione sull’emulatore. Dovrebbe funzionare. A livello di server, è possibile autorizzare o meno le intestazioni CORS nella classe [ApplicationModel]:
// dati di configurazione
private boolean CORSneeded = false;
Questo non ha alcuna importanza per l'applicazione Android, poiché non viene eseguita in un browser. Il requisito relativo alle intestazioni CORS proviene infatti dal browser e non dal server.
4.5. Distribuzione del client Angular sull'emulatore di uno smartphone Android
Ripetiamo l’operazione precedente con un emulatore per smartphone. Vogliamo verificare come si comporta il nostro client su schermi di piccole dimensioni:
![]() |
- in [1], si avvia un emulatore di smartphone;
- in [2] e [3], la barra di navigazione è stata nascosta in un menu;
![]() |
- in [4], si effettua l'accesso;
- in [5], l'elenco e il calendario sono uno sotto l'altro invece che uno accanto all'altro;
![]() |
- in [6], si richiede l'agenda;
- in [7], poiché lo schermo è troppo piccolo, una parte delle fasce orarie risulta nascosta. È stata la libreria [footable] a svolgere questo compito;
![]() |
- in [8], la stessa vista di prima, ma questa volta con un appuntamento.
In definitiva, la nostra applicazione si adatta piuttosto bene allo smartphone. Sicuramente potrebbe essere migliorata, ma rimane comunque utilizzabile.





























