Upload
josino-rodrigues
View
2.690
Download
1
Embed Size (px)
Citation preview
Grails Josino Rodrigues Neto
Um pouco do que veremos!!!!!!
Hands On Grails
Agora vou mostrar o caminho!!!
Novas Idéias
Antiga tecnologias
Antigas Tecnologias
Arquitetura de plugins
E agora? O que fazer?
Go to Prompt
grails create-app PrimeiraApp
cd PrimeiraApp
grails create-domain-class Participante
grails create-controller primeiraapp.Participante
Estruturas de pastas do Grails
So, let's go
Altere a classe de domínio package primeiraapp
class Participante {
String nome
String login
String senha
String email
String endereco
String telefone
static constraints = { }
}
Altere a classe controller package primeiraapp
class ParticipanteController {
static scaffold = true
}
Go to Prompt
grails clean
grails run-app
Scaffolding
• Gera views
• Gera classes de Controller
• Tudo automagicamente
Hora de pensar nas classes de domínio
Mas antes ...
Groovy???
Groovy é uma linguagem ágil dinâmica para a plataforma java com muitas funcionalidades inspiradas de linguagens como Python, Ruby e Smalltalk, disponibilizando tais funcionalidades para os desenvolvedores Java em uma sintaxe muito semelhante a Java.
Mapeando Groovy
Olha a diferença
Groovy Beans
• Métodos públicos por padrão
• Métodos de acesso por padrão
• Acesso simplificado a atributos de Beans
Groovy Beans class Car {
String name
}
def car = new Car()
car.setNome('Civic')
car.getNome()
car.nome
GString
def nick = 'Gina'
def book = 'Groovy in Action'
def isEquals = "$nick is $book" == 'Gina is
Groovy in Action'
Tudo é Objeto
Números def x = 1
def y = 2
println x + y == 3
println x.plus(y) == 3
println x instanceof Integer
Listas
def nomes = ['André', 'Faria']
println nomes[1]
nomes[2] = 'Gomes'
println nomes
Mapas def http = [ 100:'CONTINUE',
200:'OK',400:'BAD REQUEST']
println http[200]
println http[300]
Intervalos (Ranges)
def x = 1..10
println x
println x.size()
println x.from
println x.to
Null também significa false
def variavel = null
if(variavel){
println 'Não passa aqui'
} else {
println 'Passa aqui'
}
For in for (index in 1..10){
println index
}
def list = [0,1,2,3,4,5]
for (item in list){
println item
}
Each
def list = [0,1,2,3,4,5]
list.each() { item ->
println item
}
it new File('myfile.txt').eachLine{
println it
}
Mais informações em: http://groovy.codehaus.org/Portuguese+Home
...
Voltando ao assunto
Classes de domínio
Sim, criei uma entidade. Mas, e os
relacionamentos??
One-to-One
grails create-app Editora cd Editora grails create-domain-class Livro grails create-domain-class Autor grails create-controller editora.Livro grails create-controller editora.Autor
package editora
class Autor {
String nome
static constraints = { }
}
package editora
class Livro {
String nome
Autor autor
static constraints = { }
}
One-to-One
Altere os Controllers package editora
class LivroController {
static scaffold = true
}
package editora
class AutorController {
static scaffold = true
}
O que acontece com o BD? CREATE TABLE autor
(
id bigint NOT NULL,
version bigint NOT NULL,
nome character varying(255) NOT NULL,
CONSTRAINT autor_pkey PRIMARY KEY (id)
);
CREATE TABLE livro
(
id bigint NOT NULL,
version bigint NOT NULL,
autor_id bigint NOT NULL,
nome character varying(255) NOT NULL,
CONSTRAINT livro_pkey PRIMARY KEY (id),
CONSTRAINT fk6236e961d71d4e0 FOREIGN KEY (autor_id)
REFERENCES autor (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
package editora
class Autor {
String nome
Livro livro
static constraints = { }
}
package editora
class Livro {
String nome
static belongsTo = [autor: Autor]
static constraints = { }
}
One-to-One Bi-direcional
One-to-Many
One-to-Many package editora
class Livro {
String nome
Autor autor
static constraints = {}
}
package editora
class Autor {
String nome
static hasMany = [livro : Livro]
static constraints = {}
}
Many-to-Many
Many-to-Many package editora
class Livro {
String nome
static hasMany = [autores : Autor]
static constraints = { }
}
package editora
class Autor {
String nome
static belongsTo = Livro
static hasMany = [livros : Livro]
static constraints = { }
}
• Grails cria uma tabela de junção autor_livros • O Relacionamento será mantido pelo lado
muitos
• No caso do exemplo anterior, será mantida através do cadastro de Livros
Many-to-Many
Customizando telas Mas telas geradas para o many-to-many não são muito boas.
KD os arquivos de tela ? Como faço o pra alterar as páginas?
Nem tudo são flores. Alguma hora vocês tinham que programar.
Então, mãos à massa
grails generate-all editora.Autor grails generate-all editora.Livro
Isso recria as classes de controller e gera os arquivos da camada de visão
Controller O controller é gerado com algumas ações:
– Index : redireciona para list – List: motra uma lista paginada – Show: mostra todas as propriedades de uma
instancia – Delete: apaga um registro – Edit: mostra o formulário de edição e submete
para “update” – Update: salva as alterações em um registro – Create: mostra o formulário para cadastrar um
registro e redireciona para “save” – Save: salva um objeto no banco
View • Dentro de “grails-app/views” são gerados os
arquivos GSP(Groovy Server Pages).
• Dentro de uma pasta com o nome da entidade são criados: – create.gsp
– edit.gsp
– list.gsp
– show.gsp
Copie esse código e coloque no create.gsp
<tr class="prop"> <td valign="top" class="name"> <label for="autores"> <g:message code="livro.autores.label" default="Autores" /> </label> </td> <td valign="top" class="value ${hasErrors(bean: livroInstance, field: 'autores', 'errors')}"> <g:select name="autores" from="${editora.Autor.list()}" multiple="yes" optionKey="id" size="5" value="${livroInstance?.autores*.id}" /> </td> </tr>
Sim, e as regras de negócio ????
Constraints • blank • creditCard • email • inList • matches • max • maxSize • min • minSize
• notEqual • nullable • range • scale • size • unique • url • validator • widget
Exemplos login(blank:false)
Error Code: className.propertyName.blank
homeEmail(email:true)
Error Code: className.propertyName.email.invalid
name(inList:["Joe", "Fred", "Bob"])
Error Code: className.propertyName.not.inList
login(matches:"[a-zA-Z]+")
Error Code: className.propertyName.matches.invalid
homePage(url:true)
Error Code: className.propertyName.url.invalid
Internacionalização Veja o arquivo grails-app/i18n/message.properties
Mas tem também ... grails-app/i18n/message_pt_BR.properties grails-app/i18n/message_pt_PT.properties ... grails-app/i18n/message_es.properties
Internacionalização
Agora é só alterar os arquivos e pronto!!!!
Services • Classes Service são Plain Old Groovy Object
(POGO) localizadas na pasta grails-app/services
• E com o nome terminado com Service
• São uma forma fácil de extrair código extra de dentro dos Controllers
• Para criar um service:
grails create-service Task
Services class TaskService {
boolean transactional = true
def serviceMethod() {
…
}
}
class TekEventController {
def taskService
def index = {
taskService.serviceMethod()
redirect(action:list,params:params)
}
}
E a segurança???
Autenticação e controle de acesso
Plugins • O que o Grails não tem nativamente a
solução pra tudo • A idéia é que uma funcionalidade seja
empacotada em módulos que podem ser carregados pelo framework e integrados ao seu sistema
• Pesquisa em texto puro, tag clouds, extensões de UI, login e controle de acesso, etc…
• Acesse: http://www.grails.org/plugins
Mãos à obra Instalando plugins spring-security-core
grails install-plugin spring-security-core grails s2-quickstart editora.access SecUser Role Requestmap
Altere o BootStrap.groovy class BootStrap {
def springSecurityService
def init = {
servletContext ->
String password =
springSecurityService.encodePassword('123')
}
def destroy = { }
}
Altere o BootStrap.groovy def userAdmin = new SecUser(username: 'admin', enabled: true,
password: password).save()
def adminRole = new Role(authority: 'ROLE_ADMIN').save()
SecUserRole.create userAdmin, adminRole, true
new Requestmap(url: '/js/**', configAttribute:
'IS_AUTHENTICATED_ANONYMOUSLY').save()
new Requestmap(url: '/css/**', configAttribute:
'IS_AUTHENTICATED_ANONYMOUSLY').save()
new Requestmap(url: '/images/**', configAttribute:
'IS_AUTHENTICATED_ANONYMOUSLY').save()
new Requestmap(url: '/login/**', configAttribute:
'IS_AUTHENTICATED_ANONYMOUSLY').save()
new Requestmap(url: '/logout/**', configAttribute:
'IS_AUTHENTICATED_ANONYMOUSLY').save()
new Requestmap(url: '/**', configAttribute: 'ROLE_ADMIN').save()
Pronto Controle de acesso terminado
Agora é só praticar e perguntar!!!
Um modelo bem simples
Go to Prompt
grails create-domain-class Lance
grails create-controller primeiraapp.Lance
grails create-domain-class Leilao
grails create-controller primeiraapp.Leilao
grails create-domain-class ItemLeilao
grails create-controller primeiraapp.ItemLeilao
Atividade da semana • Trabalho em equipe(5 pessoas)
• Criar um sistema em grails com o assunto visto até aqui
• O sistema deve ter no mínimo 20 entidades
• Deve possuir controle de acesso
• A modelagem vocês decidem
• Apresentar na próxima aula os pontos positivos e negativos durante o uso da tecnologia
Mas lembrem-se, não existe bala de prata
Bibliografia Brown, Jeff; Rocher, Graeme (January 15, 2009), The Definitive Guide to Grails (2nd
ed.), Apress, pp. 648, ISBN 1590599950
Smith, Glen; Ledbrook, Peter (June 28, 2009), Grails in Action (1st ed.), Manning
Publications, pp. 520, ISBN 1933988932
Dickinson, Jon (May 27, 2009), Grails 1.1 Web Application Development (1st ed.),
Packt Publishing, pp. 328, ISBN 1847196683
Abdul-Jawad, Bashar (December 2, 2008), Groovy and Grails Recipes (1st ed.), Apress,
pp. 424, ISBN 143021600X
Fischer, Robert (April 20, 2009), Grails Persistence with GORM and GSQL (1st ed.),
Apress, pp. 125, ISBN 1430219262
M. Judd, Christopher; Nusairat, Joseph Faisal; Shingler, Jim (June 18, 2008), Beginning
Groovy and Grails: From Novice to Professional (1st ed.), Apress, pp. 440, ISBN
1430210451
Rudolph, Jason (February 6, 2007), Getting Started with Grails (1st ed.), Lulu.com, pp.
132, ISBN 143030782X