22. Conclusione
Rivediamo ciò che abbiamo fatto in questo documento. Abbiamo esaminato due livelli [DAO] utilizzando una delle due architetture seguenti:
![]() |
![]() |
Il livello [DAO1] è stato implementato con Spring JDBC e il livello [DAO2] con Spring JPA. I livelli [DAO1] e [DAO2] hanno implementato la stessa interfaccia [IDAO], il che ci ha permesso di scrivere un unico test [JUnitTestDao] per testare entrambi i livelli [DAO];
Una volta fatto ciò, abbiamo esposto l'interfaccia [IDAO] sul web come segue:
![]() |
- In [1], il livello [IDAO] è stato reso accessibile sul web tramite un livello web [2] implementato utilizzando Spring MVC. È infatti l'interfaccia [IDAO] ad essere esposta, e abbiamo realizzato due versioni del servizio web a seconda che tale interfaccia fosse implementata utilizzando un'architettura [DAO-JDBC] o [DAO-JPA-JDBC];
- in [B], un client remoto utilizza gli URL resi disponibili dal servizio web, che consentono l'accesso ai metodi del livello [IDAO-server]. Abbiamo verificato che il livello [DAO-Client] [3] implementi l'interfaccia [IDAO-server] [1]. Ciò ci ha permesso di riutilizzare lo stesso test [JUnitTestDao] che era già stato utilizzato due volte;
- In [3], il livello [DAO-Client] è stato implementato utilizzando Spring RestTemplate;
Fatto ciò, abbiamo protetto l'accesso al servizio web:
![]() |
- in [5], la richiesta HTTP del client passa attraverso un livello di autenticazione implementato con Spring Security;
Una volta fatto ciò, abbiamo evoluto l'architettura precedente nella seguente:
![]() |
- in [3], l'applicazione client è essa stessa un'applicazione web servita dal server web [4]. L'applicazione client visualizza un modulo [5] nel browser che consente di interrogare gli URL del servizio web sicuro. L'accesso HTTP al servizio web sicuro è gestito da un livello [jS] implementato in JavaScript. Questa architettura utilizza le cosiddette richieste cross-domain:
- il servizio web presenta URL del tipo [http://machine1:port1/];
- l'applicazione web client viene scaricata da un URL [http://machine2:port2/]. Se [http://machine2:port2/] non è identico a [http://machine1:port1/] (stessa macchina, stessa porta), il browser client bloccherà le chiamate HTTP provenienti dal livello [DAO-client-js]. Per risolvere questo problema, il servizio web deve consentire le richieste cross-domain;
I progetti presentati sono stati testati con i seguenti sei database:
- MySQL 5 Community Edition;
- SQL Server 2014 Express;
- PostgreSQL 9.4;
- Oracle Express 11g Release 2;
- IBM DB2 Express-C 10.5;
- Firebird 2.5.4;
Per ciascuno di questi DBMS, abbiamo sviluppato quattro diversi livelli [DAO]:
- un livello implementato con Spring JDBC;
- un livello implementato con Spring JPA e il provider JPA Hibernate;
- un livello implementato con Spring JPA e il provider JPA EclipseLink;
- un livello implementato con Spring JPA e il provider JPA OpenJPA;
È stata quindi presentata una serie di ventiquattro diverse configurazioni. È stato compiuto un grande sforzo per la rifattorizzazione del codice:
- la maggior parte del codice è stata scritta una sola volta. Si basa su due progetti di configurazione Maven:
- uno configura il livello JDBC;
- l'altro configura il livello JPA;
![]() |
![]() |
Il progetto di configurazione Maven per il livello JDBC [1] di un DBMS specifico consente:
- importare l'archivio del driver JDBC;
- di definire le credenziali di accesso per il database in uso e le varie istruzioni SQL che il livello [DAO1] invierà al driver JDBC. Sebbene l'SQL sia standardizzato, abbiamo riscontrato problemi di portabilità dovuti principalmente alla presenza nelle query di nomi di tabelle/colonne che si sono rivelati parole chiave proibite in alcuni DBMS (la tabella ROLES per DB2, la colonna PASSWORD per Firebird). Inoltre, sebbene un nome di colonna sia normalmente insensibile alle maiuscole/minuscole, abbiamo riscontrato un problema con PostgreSQL riguardo alla colonna ID della chiave primaria nelle tabelle. Richiedeva che fosse denominata "id" in minuscolo;
I tre progetti Maven per la configurazione del livello JPA [2] di un DBMS specifico consentono:
- importare l'archivio di implementazione JPA;
- configurare l'implementazione JPA utilizzata per lo specifico DBMS collegato. Infatti, è il livello JPA che invia i comandi SQL al livello JDBC. Per essere efficace, deve conoscere il DBMS al fine di inviargli comandi SQL che esso riconoscerà. Questi comandi possono utilizzare l'SQL proprietario di quel DBMS così come le sue caratteristiche specifiche (tipi di dati, sequenze, trigger, procedure, generazione automatica di chiavi primarie, ecc.);
Abbiamo quindi creato ventiquattro progetti di configurazione Maven (4 configurazioni × 6 DBMS) su cui si basavano tutti gli altri progetti di gestione del database. Nei diagrammi sopra riportati, poiché i livelli [DAO1] e [DAO2] forniscono la stessa interfaccia, le 24 configurazioni delle due architetture sopra indicate sono state testate utilizzando un'unica classe di test [JUnitTestDao]. Una volta verificate queste architetture, non ci sono state ulteriori difficoltà:
- il progetto Maven per la pubblicazione del database sul web si basa su queste due architetture. Esistono quindi anche qui 24 possibili configurazioni;
- il progetto Maven per la protezione dell'accesso al servizio web si basa sul progetto precedente e presenta anch'esso 24 possibili configurazioni;
- infine, il progetto Maven che consente le richieste cross-domain al servizio web protetto si basa sul progetto precedente e presenta anch'esso 24 possibili configurazioni;
Sebbene questo documento non copra tutte le funzionalità del linguaggio Java né tutti i suoi ambiti di applicazione, può essere utilizzato come risorsa di apprendimento per il linguaggio. I lettori che avranno padroneggiato il contenuto di questo corso avranno raggiunto un livello di “Java avanzato” sia nell’uso del linguaggio che del framework Spring. Potranno quindi proseguire la loro formazione su Java con i seguenti libri:
- [Spring MVC and Thymeleaf by Example] [http://tahe.developpez.com/java/springmvc-thymeleaf], che continua l'esplorazione dell'ecosistema Spring introducendo il suo ramo della "programmazione web MVC". Utilizza un database più complesso di quello studiato qui;
- [Tutorial AngularJS / Spring MVC] [http://tahe.developpez.com/angularjs-spring4] che presenta un'architettura web client/server, in cui il client è implementato utilizzando il framework [AngularJS] e il server utilizzando [Spring MVC];
- [Introduzione a Java EE] [http://tahe.developpez.com/java/javaee], che si allontana dall'ecosistema Spring per passare a un'architettura web basata su JSF (Java Server Faces) ed EJB (Enterprise JavaBeans);
- [Introduzione alla programmazione per tablet Android] [http://tahe.developpez.com/android/exemples-intellij-aa], che descrive un'architettura client/server in cui il client è un tablet Android programmato in Java e il server è un servizio web implementato utilizzando Spring MVC;






