Ciao Mondo! Ciao Spring MVC!

In questa puntata introduciamo alcuni aspetti fondamentali di Spring Web MVC, il framework della famiglia Spring dedicato allo sviluppo web.

Per l’occasione, costruiremo una semplicissima applicazione-hello-world, come prevede la tradizione.

Ma prima partiamo dalle basi…

Il pattern MVC… visto da Spring

Come si può facilmente intuire dal nome, Spring Web MVC (o più semplicemente Spring MVC) implementa il noto pattern MVC.

Per chi non lo conoscesse, MVC è uno dei pattern architetturali più utilizzati nell’implementazione di interfacce utente (UI), soprattutto in ambito web.

Esso si basa su tre componenti fondamentali:

  • Model: rappresenta il dominio dell’applicazione, gestisce le logiche di business e di accesso ai dati;
  • View: ha il compito di presentare i dati all’utente e consente a quest’ultimo l’interazione con l’applicazione;
  • Controller: gestisce l’interazione con l’utente tramite la View, intercetta richieste e fornisce risposte in base allo stato del Model.

L’obiettivo di MVC è quello di separare in modo netto la struttura dei componenti interni dell’applicazione dal modo in cui essi vengono presentati all’utente; di conseguenza, anche il modo in cui l’utente interagisce con questi oggetti è svincolato dalla loro rappresentazione.

A voler essere pignoli, Spring MVC implementa solamente due componenti del pattern: View e Controller. L’implementazione del Model è infatti delegata alle classi di servizio (Service) e ai Repository per l’accesso ai dati. Fortunatamente Spring fornisce altri utili strumenti per lo sviluppo di queste logiche.

Nota Il framework Spring MVC mette a disposizione l’interfaccia Model che però non va confusa con l’omonimo componente del pattern MVC. L’interfaccia Model, infatti, costituisce solamente un veicolo per il passaggio dei dati dal Controller alla View, e viceversa.

Ora però cerchiamo di farci un’idea di come funziona Spring MVC.

Configurazione del progetto

Abbiamo già visto come generare la struttura di un progetto Spring Boot in un precedente articolo.

Anche in questo caso ci faremo aiutare da Spring Initializr e per questo tutorial utilizzerò le seguenti impostazioni:

  • gestirò progetto con Maven;
  • userò il linguaggio Java;
  • la versione di Spring Boot sarà la 1.5.6;
  • Group: com.davioooh, Artifact: ciao-mondo;
  • come unica dipendenza selezionerò Thymeleaf.

Una volta generata l’impalcatura (scaffold) del progetto, siamo pronti a dare vita alla nostra applicazione aggiungendo un po’ di codice…

Creiamo un Controller

Come già accennato, il Controller ha il compito di “proiettare” lo stato del Model sulla View e, allo stesso tempo, quello d’intercettare gli input ricevuti dalla vista e riportarli nel Model.

Definire un Controller con Spring MVC è piuttosto semplice. Basta creare una nuova classe ed annotarla con @Controller:

package com.davioooh.ciaomondo.controllers;

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

@Controller
public class SalutiController {

  @RequestMapping("/")
  public String unSaluto(){
    return "ciao-mondo";
  }
}

L’annotazione @Controller è una specializzazione di @Component; un Controller in Spring MVC rappresenta infatti un tipo particolare di componente, la cui creazione è gestita dallo Spring IoC container.

Spring non pone vincoli sul nome da assegnare alle classi, ma è uso comune e buona norma usare per i nomi dei componenti un suffisso che ne identifichi la tipologia. Allo stesso modo, non esistono restrizioni particolari sulla struttura dei package. Personalmente mi piace organizzare le classi in package che facilitino la navigazione all’interno del progetto, per cui ho creato il SalutiController nel package com.davioooh.ciaomondo.controllers.

Continuando l’esplorazione del nostro Controller, notiamo che il metodo unSaluto si limita a restituire una stringa, ma non per questo va sottovalutato… :-)

L’annotazione @RequestMapping viene utilizzata per indicare i metodo addetti alla gestione delle richieste HTTP. Nel nostro caso l’annotazione registra nel contesto dell’applicazione un handler per le chiamate dirette verso la root (/) dell’applicazione.

Infine, la stringa "ciao-mondo" identifica la pagina (View) restituita/visualizzata ogni volta che una chiamata HTTP viene intercettata dal nostro handler method.

La pagina dei saluti

La pagina che mostra i nostri primi saluti è definita in un file HTML che più “statico” non si può…

<!DOCTYPE html>
<html>
<head>
  <title>Pagina dei saluti</title>
</head>
<body>
  <h1>Ciao Mondo!</h1>
</body>
</html>

Al di là del codice piuttosto banale, però, a noi interessa capire come questa pagina viene recuperata ed utilizzata per generare la risposta del Controller.

Spring Boot supporta l’integrazione con diverse tecnologie e librerie dedicate alla costruzione delle View (comprese le classiche JSP). Al momento, la scelta raccomandata è sicuramente Thymeleaf, che, se ricordate bene, abbiamo già incluso tra le dipendenze del nostro progetto.

Brevemente, Thymeleaf è un template engine per lo sviluppo di applicazioni web, che consente di creare in modo molto naturale pagine dinamiche, strutturando il codice HTML in elementi riutilizzabili.

Includendo lo starter package spring-boot-starter-thymeleaf tra le dipendenze del progetto, verrà configurato di default il caricamento dei template HTML dalla directory /resources/templates.

Nel nostro Controller avevamo specificato la pagina da usare per i saluti: "ciao-mondo". Il framework cercherà dunque di recuperare dalla directory dei template il file ciao-mondo.html (l’estensione html è quella prevista dalla configurazione automatica).

Lanciamo l’applicazione

Bene, i pezzi ci sono tutti. Non rimane altro da fare che lanciare la nostra applicazione.

Cliccate Run sul vostro IDE preferito, oppure se non volete scomodare strumenti particolarmente avanzati, potete sfruttare Maven dalla linea di comando (tramite il Maven Wrapper incluso nel progetto):

./mvnw package && java -jar target/ciao-mondo-0.0.1-SNAPSHOT.jar

Se tutto è in ordine, nella vostra console dovreste vedere qualcosa del genere:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.6.RELEASE)

2017-08-26 16:31:09.444  INFO 9243 --- [main] c.d.ciaomondo.CiaoMondoApplication       : Starting CiaoMondoApplication v0.0.1-SNAPSHOT on david-notebook with PID 9243 (/home/david/git/ciao-mondo/target/ciao-mondo-0.0.1-SNAPSHOT.jar started by david in /home/david/git/ciao-mondo)
2017-08-26 16:31:09.456  INFO 9243 --- [main] c.d.ciaomondo.CiaoMondoApplication       : No active profile set, falling back to default profiles: default

...

2017-08-26 16:31:16.541  INFO 9243 --- [main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-08-26 16:31:16.557  INFO 9243 --- [main] c.d.ciaomondo.CiaoMondoApplication       : Started CiaoMondoApplication in 8.077 seconds (JVM running for 10.96)

Non riporto per intero il log di avvio dell’applicazione, vi faccio solo notare che nella penultima riga viene indicato l’avvio di un istanza di Tomcat in ascolto sulla mitica porta 8080.

Provate a puntare il vostro browser su localhost:8080 e finalmente…

Ciao Mondo

In conclusione

In questo post abbiamo fatto una rapida carrellata delle principali caratteristiche del framework Spring MVC.

Il supporto di Spring Boot semplifica estremamente la fase iniziale di creazione e configurazione del progetto, grazie ad un esteso utilizzo di convention over configuration.

Avremo modo, in futuro, di parlare nuovamente di Spring MVC e di approfondire alcune tematiche interessanti che riguardano questo framework.

Per il momento vi saluto e vi auguro buon lavoro.

A presto,

David