Play! Framework
Keuller Magalhães
keuller.magalhaes@gmail.com
www.playframework.com.br
2013
2
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Distribuição
3
Agenda

Arquitetura de Componentes

Projeto

Rotas e Controladores

Modelos

Views

Distribuição
4
Arquitetura de Componentes
HTTP
Routes
Cotroladores
Model ModelHTML XML JSON
Baseada em padrões:
● MVC
● Page Controller
● Separation of Concern
● DRY
● Active Record
● Low Coupling
● High Cohesion
● Single Responsability
● Interface segregation
● Dependency Inversion
● YAGNI
5
Arquitetura de Componentes
●
Componentes:
●
Rotas (URLs)
●
Controladores (fluxo)
●
Modelos (entidades)
●
Templates (views)
●
Extensão através de plugins
●
Suporte a aplicações modulares
6
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views
7
Estrutura da Aplicação
 Precisa de uma versão do Java 1.6+

Podemos fazer o download do Play!
www.playframework.org

Devemos descompactá-lo numa pasta

Adicionamos o caminho da pasta no classpath do
sistema
8
Estrutura da Aplicação

Acessando o console do Play!
$ play

Para compilar nossa aplicação, basta digitar
$ compile

Para executarmos a aplicação, basta digitar:
$ run

Apontamos o navegador para a URL:
http://localhost:9000/
9
Estrutura da Aplicação
10
Estrutura da Aplicação
 Limpando código do projeto
$ clean

Preparando projeto para Eclipse/IDEA
$ eclipse | idea

Executando os testes automatizados
$ test

Preparando a aplicação para implantação
$ clean compile stage

Atualizando as dependências do projeto
$ update
11
Agenda
 Arquitetura de Componentes

Projeto

Rotas e Controladores

Modelos

Views

Distribuição
12
Rotas e Controladores

Rotas são mapeamentos entre URL e controladores
 O arquivo conf/routes contem a definição de
todas as rotas de sua aplicação
GET   /     controllers.Application.index()

Esse mapeamento nos dá três informações:
 Método HTTP usado GET

Caminho da requisição /
 Método de ação index() da classe Application
13
Rotas e Controladores
 Play suporta todos os métodos HTTP do protocolo

GET, POST, PUT, DELETE, OPTIONS, HEAD, etc

Formato da URI

URI estática
GET    /list    controllers.Cliente.list()

URI dinâmica
GET    /edit/:id   controllers.Cliente.editar(id: Integer)

URI abrangente
GET   /imagem/*arquivo   controllers.Util.imagem(arquivo)
14
Rotas e Controladores

URI com parâmetros fixos
GET   /   controllers.Teste.show(page = “index”)

URI com parâmetros padrão
GET   /    controllers.Teste.show(page ?= “index”)

Prioridade entre as Rotas

As primeiras rotas na declaração terão prioridade perante as
demais
 Todas as rotas são compiladas no objeto routes, podendo
acessá-las via código Java, da seguinte forma:
routes.Application.index()
15
Rotas e Controladores
 Play! é um framework MVC (baseado em ação)

Um controlador é uma classe Java dentro do pacote
controllers e que estende a classe Controller

Uma ação é um método público estático que retorna
um objeto Result

Tipos de Result:

ok()

redirect()

notFound()

badRequest()

status()
16
Rotas e Controladores

Vejamos o controlador padrão:
package controllers;
import play.*;
import play.mvc.*;
import views.html.*;
public class Application extends Controller {
  
  public static Result index() {
    return ok(index.render("Your new application is ready."));
  }
}
17
Rotas e Controladores

Vamos definir as rotas para nossa aplicação
# ponto de entrada da aplicacao
GET    / controllers.Application.index()
# CRUD tarefas
GET /tarefas controllers.TarefaController.lista()
POST /tarefas controllers.TarefaController.criar()
POST /tarefas/excluir/:id
controllers.TarefaController.excluir(id: Int)

Temos 3 rotas, sendo que:
primeira: lista as tarefas existentes
segunda: cria uma nova tarefa
terceira: remove uma tarefa pelo id
18
Rotas e Controladores

Vamos definir a classe controladora
public class TarefaController extends Controller {
   public static Result lista() {
      return TODO;
   }
   public static Result criar() {
   return TODO;
   }
   public static Result excluir(Integer id) {
      return TODO;
   }
}
TODO é um tipo de retorno 501 Not Implemented, útil durante o desenvolvimento.
19
Rotas e Controladores

Se executarmos nossa aplicação, veremos
20
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Distribuição
21
Modelos

Um objeto de modelo é na verdade um POJO

O modelo pode ser usado como uma
representação da uma entidade do banco de dados

Play! oferece suporte a dois mecanismos de
persistência (ORM):

Ebean

JPA
 A configuração padrão usa Ebean ORM
22
Modelos
 Criando nosso objeto de modelo
public class Tarefa {
public Integer id;
public String descricao;
public static List<Tarefa> readAll() {
   return new ArrayList<Tarefa>();
}
public static void create(Tarefa bean) {
}
public static void delete(Integer id) {
}
}
23
Modelos

Por padrão Play! usa o banco H2 embarcado

Para utilizarmos o MySQL5, precisamos do driver
 Edite o arquivo project/Build.scala
val appDependencies = Seq(
   “mysql” % “mysql­connector­java” % “5.1.25”,
   javaCore,
   javaJdbc,
   JavaEbean
)
24
Modelos

Configurando nossa conexão com banco de dados
 Edite o arquivo conf/application.conf
db.default.driver=”com.mysql.jdbc.Driver”
db.default.url=”jdbc:mysql://localhost/play”
db.default.user=root
db.default.password=”admin123”

Para ativar o controle do Ebean, devemos descomentar
ebean.defaults=”models.*”

Precisamos transformar nosso modelo numa
entidade persistente
25
Modelos
 Adaptando nossa classe de modelo
@Entity
public class Tarefa extends Model {
@Id
public Integer id;
@Column(length=35)
public String descricao;
public static Finder<Integer,Tarefa> finder =
    new Finder(Integer.class, Tarefa.class);
...
}
26
Modelos
 Implementando os métodos de persistência
@Entity
public class Tarefa extends Model {
...
        public static List<Tarefa> readAll() {
           return finder.all();
        }
        public static void create(Tarefa bean) {
           bean.save();
        }
        public static void delete(Integer id) {
           finder.ref(id).delete();
        }
}
27
Modelos

Para suporte a transações devemos usar a anotação
@Transactional
public class TarefaController extends Controller {
@play.db.ebean.Transactional
        public static void criar() {
           ...
        }
}
 Devemos usar a anotação @Transactional quando
temos operações de escrita

Em operações de leitura devemos usar o atributo
readOnly=true na anotação @Transactional
28
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição
29
Views

Uma é um template de página HTML com código de
script Scala

Todo template é compilado em byte code

Todo template deve estar contido na pasta views

Todo template deve ter a extensão .scala.html

Play! ainda não possui uma biblioteca de
componentes visuais para criação de interfaces
gráficas
30
Views

Vejamos o template da view →
app/views/index.scala.html
@(message: String)
@main(“Welcome Play 2.0”) {
 @play20.welcome(message)
}

Neste caso estamos criando uma view, baseada
numa página de layout padrão main.scala.html
31
Views

Templates podem receber parâmetros de qualquer
tipo de dados

Usamos o caracter especial @ para informar comando
Scala no template

Em nosso exemplo anterior, estamos passando um
parâmetro do tipo String, na variável message
@(message: String)
32
Views

O mecanismo de templates do Play! nos permite
reutilizar outros templates

views bases para as páginas da aplicação

Em nosso exemplo anterior, estamos usando o
template main.scala.html como base da nossa
página
33
Views

Vejamos o código do template index.scala.html
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
    <title>@title</title>
    <link rel="stylesheet" media="screen" 
          href="@routes.Assets.at("css/main.css")">
    <link rel="shortcut icon" type="image/png" 
          href="@routes.Assets.at("images/favicon.png")">
    <script type="text/javascript" 
src="@routes.Assets.at("javascripts/jquery­1.9.0.min.js")">
</script>
</head>
<body>
    @content
</body>
</html>
34
Views
@(tasks: List[Tarefa], taskForm: Form[Tarefa])
@import helper._
@main("Lista de Tarefas") {    
    <h1>@tasks.size() tarefa(s)</h1>    
    <ul>
        @for(task <­ tasks) {
            <li>
                @task.descricao
                @form(routes.TarefaController.excluir(task.id)) {
                    <input type="submit" value="Delete">
                }
            </li>
        }
    </ul>
}
35
Views

No template anterior criamos um código para
exibir uma lista de tarefas, bem simples

Nosso template recebe dois parâmetros

uma lista de tarefas

um objeto Form, baseado em nosso modelo
@(tasks: List[Tarefa], taskForm: Form[Tarefa])

Logo após realizamos a importação de helpers
   @import helper._
 Depois usamos um comando @for() padrão para
exibir os itens da coleção tasks
36
Views
●
Para completar nosso template, adicionamos o código a
seguir:
    <h2>Criar tarefa</h2>
    @form(routes.TarefaController.criar()) {
        @inputText(taskForm("descricao")) 
        <input type="submit" value="Create">
    }

No trecho acima criamos um formulário usando o helper
@form()

O helper recebe como argumento a rota da ação que
deverá ser invocada, quando o formulário for submetido

Também usamos o helper @inputText() para criar uma
caixa de texto baseada num campo do formulário
37
Views
 Implementando o método de ação lista()
public class TarefaController extends Controller {
   static Form<Tarefa> taskForm = Form.form(Tarefa.class);
   // exibe a pagina index.scala.html passando dois 
   // parametros: List<Tarefa> e Form<Tarefa>
   public static Result lista() {
      return ok(views.html.index
         .render(Tarefa.readAll(), taskForm));
   }
   ...
}
38
Views
 Implementando o método de ação criar()
public class TarefaController extends Controller {
   public static Result criar() {
      Form<Tarefa> form = taskForm.bindFromRequest();
      if (form.hasErrors()) {
         return badRequest(index.render(
                    Tarefa.readAll(), form));
      }
      Tarefa.create(form.get());
      return redirect(routes.TarefaController.lista());
   }
   ...
}
39
Views
 Implementando o método de ação excluir()
public class TarefaController extends Controller {
   public static Result excluir(Integer id) {
      Tarefa.delete(id);
      return redirect(routes.TarefaController.lista());
   }
}
40
Views
 Podemos utilizar qualquer dado armazenado na sessão
do usuário para renderizar na view
public class TarefaController extends Controller {
   public static Result showInfo() {
      session(“usuario”, “Administrador”);
      session(“email”, “admin@playframework.com.br”);
      return ok(views.html.showUserInfo());
   }
}
// na view teremos
@main(“Sample”) {
   Usuario: @session(“usuario”) <br/>
   E­mail.: @session(“email”)
}
41
Views
 Devemos observar alguns pontos quanto ao uso da
sessão numa aplicação Play:

Os dados não são armazenados no servidor

Os dados são armazenados localmente via cookie

Os coolies são assinados com chave secreta que não
permite visualizar seu conteúdo

Só podemos armazenar dados do tipo String

A sessão não expira, ou seja, não possui timeout
42
Views

Existem formulários que não estão associados a
modelos de dados

Estes formulários são dinâmicos
public static Result authenticate() {
   DynamicForm dataForm = Form.form().bindFromRequest();
   String username = dataForm.get(“username”);
   String password = dataForm.get(“password”);
   // alguma validacao
   return redirect(views.html.dashboard.render());
}
43
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição
44
Segurança
 Criamos um mecanismo de segurança util e simples
usando a classe Authenticator
import play.mvc.Security;
public class Secured extends Security.Authenticator {
   public String getUsername(Context ctx) {
      return ctx.session().get(“username”);
   }
   public Result onUnauthorized(Context ctx) {
      return redirect(routes.LoginController.form());
   }
}
45
Segurança
 Usamos a anotação @Authenticated para proteger
nossos controladores ou métodos de ação
import play.mvc.Security;
@Security.Authenticated(Secured.class)
public class Application extends Controller {
   ...
}
public class Application extends Controller {
   @Security.Authenticated(Secured.class)
   public static Result admin() {
      ...
   }
}
46
Agenda
 Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição
47
Distribuição

Play suporta dois tipos de distribuição:

Distribuição direta via runtime

Distribuição via WAR (container JavaEE)

Para distribuirmos uma aplicação Play de forma direta,
precisamos gerar seu runtime, através:
$ play clean compile stage

Posteriormente basta executar o script start
$ target/start ­Xms256m ­Xmx256m ­Xss1m

Os parâmetros de memória são opcionais
48
Distribuição

Para implantarmos num contaier JavaEE, devemos utilizar
um plugin chamado play2war
https://github.com/dlecan/play2-war-plugin
 No arquivo project/plugins.sbt adicione a seguinte linha
addSbtPlugin("com.github.play2war" % "play2­war­plugin" % "1.0")
 No arquivo project/Build.scala adicione a seguinte linha
import com.github.play2war.plugin._
49
Distribuição
 Ainda no arquivo project/Build.scala adicione a seguinte
linha, nas configurações do projeto adicione
val main = play.Project(appName, appVersion, appDependencies)
   .settings(Play2WarPlugin.play2WarSettings: _*)
   .settings(
      Play2WarKeys.servletVersion := “2.5”,
      Play2WarKeys.targetName := Some(“tarefas”)
   )

No console do Play, digite
$ war

Para deploy dentro do Jboss, requer algumas
configurações especiais (veja na doc do plugin)
50
Anexo I – Ebean API
 Implementando consultas
1. Lista todos os objetos: 
Aluno.finder.all()
2. Pesquisa pelo ID: 
Aluno bean = Aluno.finder.byId(5);
3. Pesquisa condicional:
Aluno.finder.where()
   .ilike(“nome”, “%ana%”)
   .orderBy(“nascimento desc”)
   .findList();
4. Pesquisa por propriedade:
Aluno bean = Aluno.finder.where()
   .eq(“status”, Status.ATIVO)
   .orderBy(“nome asc”)
   .findList();
51
Keuller Magalhães
keuller.magalhaes@gmail.com
www.playframework.com.br

Treinamento Play Framework

  • 1.
  • 2.
    2 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views  Distribuição
  • 3.
    3 Agenda  Arquitetura de Componentes  Projeto  Rotase Controladores  Modelos  Views  Distribuição
  • 4.
    4 Arquitetura de Componentes HTTP Routes Cotroladores ModelModelHTML XML JSON Baseada em padrões: ● MVC ● Page Controller ● Separation of Concern ● DRY ● Active Record ● Low Coupling ● High Cohesion ● Single Responsability ● Interface segregation ● Dependency Inversion ● YAGNI
  • 5.
    5 Arquitetura de Componentes ● Componentes: ● Rotas(URLs) ● Controladores (fluxo) ● Modelos (entidades) ● Templates (views) ● Extensão através de plugins ● Suporte a aplicações modulares
  • 6.
    6 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views
  • 7.
    7 Estrutura da Aplicação Precisa de uma versão do Java 1.6+  Podemos fazer o download do Play! www.playframework.org  Devemos descompactá-lo numa pasta  Adicionamos o caminho da pasta no classpath do sistema
  • 8.
    8 Estrutura da Aplicação  Acessandoo console do Play! $ play  Para compilar nossa aplicação, basta digitar $ compile  Para executarmos a aplicação, basta digitar: $ run  Apontamos o navegador para a URL: http://localhost:9000/
  • 9.
  • 10.
    10 Estrutura da Aplicação Limpando código do projeto $ clean  Preparando projeto para Eclipse/IDEA $ eclipse | idea  Executando os testes automatizados $ test  Preparando a aplicação para implantação $ clean compile stage  Atualizando as dependências do projeto $ update
  • 11.
    11 Agenda  Arquitetura deComponentes  Projeto  Rotas e Controladores  Modelos  Views  Distribuição
  • 12.
    12 Rotas e Controladores  Rotassão mapeamentos entre URL e controladores  O arquivo conf/routes contem a definição de todas as rotas de sua aplicação GET   /     controllers.Application.index()  Esse mapeamento nos dá três informações:  Método HTTP usado GET  Caminho da requisição /  Método de ação index() da classe Application
  • 13.
    13 Rotas e Controladores Play suporta todos os métodos HTTP do protocolo  GET, POST, PUT, DELETE, OPTIONS, HEAD, etc  Formato da URI  URI estática GET    /list    controllers.Cliente.list()  URI dinâmica GET    /edit/:id   controllers.Cliente.editar(id: Integer)  URI abrangente GET   /imagem/*arquivo   controllers.Util.imagem(arquivo)
  • 14.
    14 Rotas e Controladores  URIcom parâmetros fixos GET   /   controllers.Teste.show(page = “index”)  URI com parâmetros padrão GET   /    controllers.Teste.show(page ?= “index”)  Prioridade entre as Rotas  As primeiras rotas na declaração terão prioridade perante as demais  Todas as rotas são compiladas no objeto routes, podendo acessá-las via código Java, da seguinte forma: routes.Application.index()
  • 15.
    15 Rotas e Controladores Play! é um framework MVC (baseado em ação)  Um controlador é uma classe Java dentro do pacote controllers e que estende a classe Controller  Uma ação é um método público estático que retorna um objeto Result  Tipos de Result:  ok()  redirect()  notFound()  badRequest()  status()
  • 16.
    16 Rotas e Controladores  Vejamoso controlador padrão: package controllers; import play.*; import play.mvc.*; import views.html.*; public class Application extends Controller {      public static Result index() {     return ok(index.render("Your new application is ready."));   } }
  • 17.
    17 Rotas e Controladores  Vamosdefinir as rotas para nossa aplicação # ponto de entrada da aplicacao GET    / controllers.Application.index() # CRUD tarefas GET /tarefas controllers.TarefaController.lista() POST /tarefas controllers.TarefaController.criar() POST /tarefas/excluir/:id controllers.TarefaController.excluir(id: Int)  Temos 3 rotas, sendo que: primeira: lista as tarefas existentes segunda: cria uma nova tarefa terceira: remove uma tarefa pelo id
  • 18.
    18 Rotas e Controladores  Vamosdefinir a classe controladora public class TarefaController extends Controller {    public static Result lista() {       return TODO;    }    public static Result criar() {    return TODO;    }    public static Result excluir(Integer id) {       return TODO;    } } TODO é um tipo de retorno 501 Not Implemented, útil durante o desenvolvimento.
  • 19.
    19 Rotas e Controladores  Seexecutarmos nossa aplicação, veremos
  • 20.
    20 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views  Distribuição
  • 21.
    21 Modelos  Um objeto demodelo é na verdade um POJO  O modelo pode ser usado como uma representação da uma entidade do banco de dados  Play! oferece suporte a dois mecanismos de persistência (ORM):  Ebean  JPA  A configuração padrão usa Ebean ORM
  • 22.
    22 Modelos  Criando nossoobjeto de modelo public class Tarefa { public Integer id; public String descricao; public static List<Tarefa> readAll() {    return new ArrayList<Tarefa>(); } public static void create(Tarefa bean) { } public static void delete(Integer id) { } }
  • 23.
    23 Modelos  Por padrão Play!usa o banco H2 embarcado  Para utilizarmos o MySQL5, precisamos do driver  Edite o arquivo project/Build.scala val appDependencies = Seq(    “mysql” % “mysql­connector­java” % “5.1.25”,    javaCore,    javaJdbc,    JavaEbean )
  • 24.
    24 Modelos  Configurando nossa conexãocom banco de dados  Edite o arquivo conf/application.conf db.default.driver=”com.mysql.jdbc.Driver” db.default.url=”jdbc:mysql://localhost/play” db.default.user=root db.default.password=”admin123”  Para ativar o controle do Ebean, devemos descomentar ebean.defaults=”models.*”  Precisamos transformar nosso modelo numa entidade persistente
  • 25.
    25 Modelos  Adaptando nossaclasse de modelo @Entity public class Tarefa extends Model { @Id public Integer id; @Column(length=35) public String descricao; public static Finder<Integer,Tarefa> finder =     new Finder(Integer.class, Tarefa.class); ... }
  • 26.
    26 Modelos  Implementando osmétodos de persistência @Entity public class Tarefa extends Model { ...         public static List<Tarefa> readAll() {            return finder.all();         }         public static void create(Tarefa bean) {            bean.save();         }         public static void delete(Integer id) {            finder.ref(id).delete();         } }
  • 27.
    27 Modelos  Para suporte atransações devemos usar a anotação @Transactional public class TarefaController extends Controller { @play.db.ebean.Transactional         public static void criar() {            ...         } }  Devemos usar a anotação @Transactional quando temos operações de escrita  Em operações de leitura devemos usar o atributo readOnly=true na anotação @Transactional
  • 28.
    28 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views  Segurança  Distribuição
  • 29.
    29 Views  Uma é umtemplate de página HTML com código de script Scala  Todo template é compilado em byte code  Todo template deve estar contido na pasta views  Todo template deve ter a extensão .scala.html  Play! ainda não possui uma biblioteca de componentes visuais para criação de interfaces gráficas
  • 30.
    30 Views  Vejamos o templateda view → app/views/index.scala.html @(message: String) @main(“Welcome Play 2.0”) {  @play20.welcome(message) }  Neste caso estamos criando uma view, baseada numa página de layout padrão main.scala.html
  • 31.
    31 Views  Templates podem receberparâmetros de qualquer tipo de dados  Usamos o caracter especial @ para informar comando Scala no template  Em nosso exemplo anterior, estamos passando um parâmetro do tipo String, na variável message @(message: String)
  • 32.
    32 Views  O mecanismo detemplates do Play! nos permite reutilizar outros templates  views bases para as páginas da aplicação  Em nosso exemplo anterior, estamos usando o template main.scala.html como base da nossa página
  • 33.
    33 Views  Vejamos o códigodo template index.scala.html @(title: String)(content: Html) <!DOCTYPE html> <html> <head>     <title>@title</title>     <link rel="stylesheet" media="screen"            href="@routes.Assets.at("css/main.css")">     <link rel="shortcut icon" type="image/png"            href="@routes.Assets.at("images/favicon.png")">     <script type="text/javascript"  src="@routes.Assets.at("javascripts/jquery­1.9.0.min.js")"> </script> </head> <body>     @content </body> </html>
  • 34.
  • 35.
    35 Views  No template anteriorcriamos um código para exibir uma lista de tarefas, bem simples  Nosso template recebe dois parâmetros  uma lista de tarefas  um objeto Form, baseado em nosso modelo @(tasks: List[Tarefa], taskForm: Form[Tarefa])  Logo após realizamos a importação de helpers    @import helper._  Depois usamos um comando @for() padrão para exibir os itens da coleção tasks
  • 36.
    36 Views ● Para completar nossotemplate, adicionamos o código a seguir:     <h2>Criar tarefa</h2>     @form(routes.TarefaController.criar()) {         @inputText(taskForm("descricao"))          <input type="submit" value="Create">     }  No trecho acima criamos um formulário usando o helper @form()  O helper recebe como argumento a rota da ação que deverá ser invocada, quando o formulário for submetido  Também usamos o helper @inputText() para criar uma caixa de texto baseada num campo do formulário
  • 37.
    37 Views  Implementando ométodo de ação lista() public class TarefaController extends Controller {    static Form<Tarefa> taskForm = Form.form(Tarefa.class);    // exibe a pagina index.scala.html passando dois     // parametros: List<Tarefa> e Form<Tarefa>    public static Result lista() {       return ok(views.html.index          .render(Tarefa.readAll(), taskForm));    }    ... }
  • 38.
    38 Views  Implementando ométodo de ação criar() public class TarefaController extends Controller {    public static Result criar() {       Form<Tarefa> form = taskForm.bindFromRequest();       if (form.hasErrors()) {          return badRequest(index.render(                     Tarefa.readAll(), form));       }       Tarefa.create(form.get());       return redirect(routes.TarefaController.lista());    }    ... }
  • 39.
    39 Views  Implementando ométodo de ação excluir() public class TarefaController extends Controller {    public static Result excluir(Integer id) {       Tarefa.delete(id);       return redirect(routes.TarefaController.lista());    } }
  • 40.
    40 Views  Podemos utilizarqualquer dado armazenado na sessão do usuário para renderizar na view public class TarefaController extends Controller {    public static Result showInfo() {       session(“usuario”, “Administrador”);       session(“email”, “admin@playframework.com.br”);       return ok(views.html.showUserInfo());    } } // na view teremos @main(“Sample”) {    Usuario: @session(“usuario”) <br/>    E­mail.: @session(“email”) }
  • 41.
    41 Views  Devemos observaralguns pontos quanto ao uso da sessão numa aplicação Play:  Os dados não são armazenados no servidor  Os dados são armazenados localmente via cookie  Os coolies são assinados com chave secreta que não permite visualizar seu conteúdo  Só podemos armazenar dados do tipo String  A sessão não expira, ou seja, não possui timeout
  • 42.
    42 Views  Existem formulários quenão estão associados a modelos de dados  Estes formulários são dinâmicos public static Result authenticate() {    DynamicForm dataForm = Form.form().bindFromRequest();    String username = dataForm.get(“username”);    String password = dataForm.get(“password”);    // alguma validacao    return redirect(views.html.dashboard.render()); }
  • 43.
    43 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views  Segurança  Distribuição
  • 44.
    44 Segurança  Criamos ummecanismo de segurança util e simples usando a classe Authenticator import play.mvc.Security; public class Secured extends Security.Authenticator {    public String getUsername(Context ctx) {       return ctx.session().get(“username”);    }    public Result onUnauthorized(Context ctx) {       return redirect(routes.LoginController.form());    } }
  • 45.
    45 Segurança  Usamos aanotação @Authenticated para proteger nossos controladores ou métodos de ação import play.mvc.Security; @Security.Authenticated(Secured.class) public class Application extends Controller {    ... } public class Application extends Controller {    @Security.Authenticated(Secured.class)    public static Result admin() {       ...    } }
  • 46.
    46 Agenda  Arquitetura deComponentes  Estrutura da Aplicação  Rotas e Controladores  Modelos  Views  Segurança  Distribuição
  • 47.
    47 Distribuição  Play suporta doistipos de distribuição:  Distribuição direta via runtime  Distribuição via WAR (container JavaEE)  Para distribuirmos uma aplicação Play de forma direta, precisamos gerar seu runtime, através: $ play clean compile stage  Posteriormente basta executar o script start $ target/start ­Xms256m ­Xmx256m ­Xss1m  Os parâmetros de memória são opcionais
  • 48.
    48 Distribuição  Para implantarmos numcontaier JavaEE, devemos utilizar um plugin chamado play2war https://github.com/dlecan/play2-war-plugin  No arquivo project/plugins.sbt adicione a seguinte linha addSbtPlugin("com.github.play2war" % "play2­war­plugin" % "1.0")  No arquivo project/Build.scala adicione a seguinte linha import com.github.play2war.plugin._
  • 49.
    49 Distribuição  Ainda noarquivo project/Build.scala adicione a seguinte linha, nas configurações do projeto adicione val main = play.Project(appName, appVersion, appDependencies)    .settings(Play2WarPlugin.play2WarSettings: _*)    .settings(       Play2WarKeys.servletVersion := “2.5”,       Play2WarKeys.targetName := Some(“tarefas”)    )  No console do Play, digite $ war  Para deploy dentro do Jboss, requer algumas configurações especiais (veja na doc do plugin)
  • 50.
    50 Anexo I –Ebean API  Implementando consultas 1. Lista todos os objetos:  Aluno.finder.all() 2. Pesquisa pelo ID:  Aluno bean = Aluno.finder.byId(5); 3. Pesquisa condicional: Aluno.finder.where()    .ilike(“nome”, “%ana%”)    .orderBy(“nascimento desc”)    .findList(); 4. Pesquisa por propriedade: Aluno bean = Aluno.finder.where()    .eq(“status”, Status.ATIVO)    .orderBy(“nome asc”)    .findList();
  • 51.