51
Play! Framework Keuller Magalhães [email protected] www.playframework.com.br 2013

Treinamento Play Framework

Embed Size (px)

DESCRIPTION

Material utilizado durante alguns treinamento de Play.

Citation preview

Page 1: Treinamento Play Framework

Play! Framework

Keuller Magalhães

[email protected]

www.playframework.com.br

2013

Page 2: Treinamento Play Framework

2

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Distribuição

Page 3: Treinamento Play Framework

3

Agenda

Arquitetura de Componentes

Projeto

Rotas e Controladores

Modelos

Views

Distribuição

Page 4: Treinamento Play Framework

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

Page 5: Treinamento Play Framework

5

Arquitetura de Componentes

● Componentes:● Rotas (URLs)

● Controladores (fluxo)

● Modelos (entidades)

● Templates (views)

● Extensão através de plugins

● Suporte a aplicações modulares

Page 6: Treinamento Play Framework

6

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Page 7: Treinamento Play Framework

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

Page 8: Treinamento Play Framework

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/

Page 9: Treinamento Play Framework

9

Estrutura da Aplicação

Page 10: Treinamento Play Framework

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

Page 11: Treinamento Play Framework

11

Agenda

Arquitetura de Componentes

Projeto

Rotas e Controladores

Modelos

Views

Distribuição

Page 12: Treinamento Play Framework

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çãoGET   /     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

Page 13: Treinamento Play Framework

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âmicaGET    /edit/:id   controllers.Cliente.editar(id: Integer)

URI abrangenteGET   /imagem/*arquivo   controllers.Util.imagem(arquivo)

Page 14: Treinamento Play Framework

14

Rotas e Controladores

URI com parâmetros fixos

GET   /   controllers.Teste.show(page = “index”)

URI com parâmetros padrãoGET   /    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()

Page 15: Treinamento Play Framework

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()

Page 16: Treinamento Play Framework

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."));  }}

Page 17: Treinamento Play Framework

17

Rotas e Controladores

Vamos definir as rotas para nossa aplicação

# ponto de entrada da aplicacaoGET    / controllers.Application.index()

# CRUD tarefasGET /tarefas controllers.TarefaController.lista()POST /tarefas controllers.TarefaController.criar()POST /tarefas/excluir/:idcontrollers.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

Page 18: Treinamento Play Framework

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.

Page 19: Treinamento Play Framework

19

Rotas e Controladores

Se executarmos nossa aplicação, veremos

Page 20: Treinamento Play Framework

20

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Distribuição

Page 21: Treinamento Play Framework

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

Page 22: Treinamento Play Framework

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) {}

}

Page 23: Treinamento Play Framework

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)

Page 24: Treinamento Play Framework

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=rootdb.default.password=”admin123”

Para ativar o controle do Ebean, devemos descomentar

ebean.defaults=”models.*”

Precisamos transformar nosso modelo numa entidade persistente

Page 25: Treinamento Play Framework

25

Modelos

Adaptando nossa classe de modelo

@Entitypublic class Tarefa extends Model {

@Idpublic Integer id;

@Column(length=35)public String descricao;

public static Finder<Integer,Tarefa> finder =    new Finder(Integer.class, Tarefa.class);

...}

Page 26: Treinamento Play Framework

26

Modelos

Implementando os métodos de persistência

@Entitypublic 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();        }

}

Page 27: Treinamento Play Framework

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

Page 28: Treinamento Play Framework

28

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição

Page 29: Treinamento Play Framework

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

Page 30: Treinamento Play Framework

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

Page 31: Treinamento Play Framework

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)

Page 32: Treinamento Play Framework

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

Page 33: Treinamento Play Framework

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>

Page 34: Treinamento Play Framework

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>

}

Page 35: Treinamento Play Framework

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

Page 36: Treinamento Play Framework

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

Page 37: Treinamento Play Framework

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));   }

   ...}

Page 38: Treinamento Play Framework

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());   }

   ...}

Page 39: Treinamento Play Framework

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());   }

}

Page 40: Treinamento Play Framework

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”, “[email protected]”);      return ok(views.html.showUserInfo());   }}

// na view teremos@main(“Sample”) {   Usuario: @session(“usuario”) <br/>   E­mail.: @session(“email”)}

Page 41: Treinamento Play Framework

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

Page 42: Treinamento Play Framework

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());

}

Page 43: Treinamento Play Framework

43

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição

Page 44: Treinamento Play Framework

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());   }}

Page 45: Treinamento Play Framework

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() {      ...   }}

Page 46: Treinamento Play Framework

46

Agenda

Arquitetura de Componentes

Estrutura da Aplicação

Rotas e Controladores

Modelos

Views

Segurança

Distribuição

Page 47: Treinamento Play Framework

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

Page 48: Treinamento Play Framework

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._

Page 49: Treinamento Play Framework

49

Distribuição

Ainda no arquivo project/Build.scala adicione a seguinte

linha, nas configurações do projeto adicioneval 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)

Page 50: Treinamento Play Framework

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();

Page 51: Treinamento Play Framework

51

Keuller Magalhães

[email protected]

www.playframework.com.br