Play 2 è un Web framework specifico per Java e Scala, esso si basa su una architettura lightweight, stateless e Web-friendly, inoltre, rappresenta un'implementazione di Akka, un motore per costruire applicazioni concorrenti, distribuite, altamente scalabili ed orientate alla Fault-Tollerance.
Installazione
Iniziamo effettuando il download del pacchetto dal sito ufficiale del progetto, nella pagina però viene indicato il package principale con l'activator, scarichiamo invece la versione da 108 mega nel link posizionato sotto la voce old version:

Una volta scaricato, il pacchetto andrà scompattato in una cartella, nel nostro caso sotto c
, per poi aggiungere alla variabile path di sistema il percorso alla cartella di installazione:

Apriamo quindi una shell Dos e digitiamo play help
, dovrebbe comparire un messaggio come quello riportato in figura:

Ora posizioniamoci sotto la cartella c (la root) e digitiamo play new MyPlayApp
questo lancerà un wizard in modalità testuale per creare la nostra prima Web application:

L'applicazione verrà creata dopo aver effettuato le semplici scelte che il wizard richiede, se infatti apriamo la cartella sotto c
:

La cartella è organizzata secondo una struttura predefinita, questa modalità ricorda in maniera evidente la Convention Over Configuration ampiamente utilizzata da Maven e non solo. Ora importiamo la nostra applicazione in Eclipse, posizioniamoci quindi sotto la cartella della nostra applicazione e digitiamo play Eclipse
. Va notato che il comando non funzionerà in maniera corretta se navighiamo attraverso un Proxy, in questo caso bisognerà impostare la variabile di ambiente HTTP_PROXY
con il valore del nostro proxy (ad esempio: http://<proxy_name>:port
) e lanciando il comando aggiungendo eventuali credenziali (ad esempio: play Eclipse -Dhttp.proxyUser=<user> -Dhttp.proxyPassword=<password>
).

Una volta importata l'applicazione potrebbe presentarsi il seguente problema:

La soluzione è piuttosto semplice basta aprire il file .classpath
e rimuovere la parte segnata in rosso nella prossima immagine:

Effettuiamo il refresh dell'applicazione in Eclipse e l'errore scomparirà.
Avviamento del server
Ora avviamo il server, digitiamo quindi da shell Dos il comando
play ~run
Digitamo poi nel browser l'url: http://localhost:9000/
; comparirà la schermata di benvenuto del nostro server:

Nota: in alcuni casi potrebbe capitare di dover arrestare il server. Mentre con la prima release del fremework era sufficiente digitare il comando play stop
, la versione 2 necessita invece di un work-around che consiste nel creare un file stop.bat
(anche nella stessa cartella del progetto) recante il seguente contenuto:
@echo off
if exist RUNNING_PID (
setlocal EnableDelayedExpansion
set /p PLAY_PID=<RUNNING_PID
echo killing pid !PLAY_PID!
taskkill /F /PID !PLAY_PID!
del RUNNING_PID
endlocal
)
Tale script arresterà il server quando necessario.
Routing e Rendering
La nostra applicazione è già in running, non abbiamo specificato il classico Context Root, ma il motore riconosce che l'applicazione di riferimento è la nostra perché abbiamo lanciato il comando play run
sotto la directory MyPlayApp
.
Play prevede la presenza di un controller che veicola le richieste HTTP verso un proprio metodo chiamato action
; è previsto sotto la cartella conf
il file routes
, contenente il mapping degli url con le corrispondenti action:

Il controller principale richiamato si trova sotto il package controllers
:

il metodo index()
è invece quello che viene richiamato quando si effettua la richiesta GET, mentre il messaggio ok enetered index verrà visualizzato dalla nostra pagina di output:

Il rendering dell'output si basa su Scala e utilizza due template :
- index.scala.html
- main.scala.html
Il primo template (il cui contenuto viene proposto nello snippet seguente) colleziona i dati passati via HTTP e li comunica al secondo:
@(message: String)
@main("Welcome to Play") {
@play20.welcome(message, style = "Java")
}
message
è il messaggio passato dal controller che viene successivamente reso disponibile al secondo template; questo invece il contenuto del template main.scala.html
:
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
<script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
</head>
<body>
@content
</body>
</html>
Si provi quindi ad aggiungere un routing personalizzato inserendo la riga seguente nel file routes
:

Una volta aperto il controller, si dovrà associare una action al path aggiunto:

Viene così specificato al motore di Play che digitando http://localhost/hello
dovrà essere richiamato il metodo hello()
del controller e visualizzato di conseguenza il messaggio ok entered hello:

Il tutto avverrà in tempo reale, senza la necessità di compiling e re-deploy.
Testing con Junit
Play 2 utilizza Junit per i test e permette di verificare anche la disponibilità di una action del controller; per testare se la nostra action hello
funziona correttamente, apriamo la classe ApplicationTest.java
sotto il package test
ed aggiungiamo il codice seguente:
@Test
public void callIndex() {
Result result = callAction(controllers.routes.ref.Application.hello());
assertThat(status(result)).isEqualTo(OK);
assertThat(contentType(result)).isEqualTo("text/html");
assertThat(charset(result)).isEqualTo("utf-8");
assertThat(contentAsString(result)).contains("ok entered hello!");
}
In esso viene specificato che, richiamando la action controllers.routes.ref.Application.hello()
, la risposta debba essere positiva e che il messaggio di risposta dovrà contenere la stringa attesa:
