Você está na página 1de 24

Grails: mais inspirao, menos transpirao

Programao web em Java nunca foi to fcil


Conveno por configurao. Esse um dos lemas que leva o Grails a
ser um dos mais atraentes frameworks MVC
De que se trata o artigo:
Criado em 2006, o Grails um recurso de desenvolvimento gil usado de
maneira mais ampla na Inglaterra e na Alemanha e que hoje tem se tornado
um dos temas que despertam curiosidade nas comunidades brasileiras de Java.
Aos poucos este framework vai ganhando mais adeptos no pas por ser uma
ferramenta que oferece velocidade na programao de aplicaes para Web.
Para que serve:
Lidar com o Grails serve como diferencial para elaborar desde projetos
complexos aos mais simples. E significa tambm estar integrado a uma
tendncia de mercado cuja exigncia de alta capacidade de dinamismo. O
uso do Grails como soluo faz com que o programador possa otimizar seu
tempo e distribu-lo melhor em tarefas qualitativas.
Em que situao o tema til:
Por ser uma ferramenta de alta produtividade que prima por uma linguagem
mais enxuta, aprender a trabalhar com o Grails representa uma vantagem
competitiva no momento de oferecer ao cliente solues e prazos. Sua grande
utilidade a de ditar ao trabalho um ritmo que supera os recursos tradicionais,
justamente por ter cdigos mais integrados e inteligveis.
Grails: mais inspirao, menos transpirao Resumo DevMan:
O conjunto de facilitadores que compe o Grails torna o cotidiano
desenvolvedores menos sacrificado no que diz respeito ao desgaste
complexidade de detalhes e codificaes. Para detalhar melhor seu uso,
artigo traz um demonstrativo prtico com a criao de um blog construdo
emprego da ferramenta.

dos
com
este
com

O Grails uma ferramenta da era do desenvolvimento gil e faz parte de uma


nova gerao de frameworks MVC para linguagens dinmicas, como o Rails (do
Ruby) ou o Django (do Python). Os agilistas trazem mandamentos curiosos
de filosofia de programao, como KISS - Keep It Simple, Stupid! (mantenha
simples, estpido!), DRY - Dont Repeat Yourself (no se repita), You Aint
Gonna Need It (voc no vai precisar disso) ou Build Less (desenvolva menos),
entre muitos outros que pregam um modelo de trabalho com menos
transpirao e mais inspirao.
O Grails uma mistura de tecnologias integradas que utiliza como seu principal
agente o Groovy, linguagem de scripting e dinamicamente tipada, orientada a
objetos, que roda de forma nativa na JVM. Uma das maiores vantagens do
Grails a conveno por configurao (troca da configurao explcita, ex.: via
cdigo ou descritores, por convenes).
O Grails imprime um jeito simples de programar e faz com que o profissional
esteja mais livre para se dedicar s regras de negcio. Tudo leva a crer que

este no seja apenas mais um concorrente no espao j bastante saturado de


frameworks web para Java.
Mas qual a diferena entre o Grails e um framework MVC qualquer?
De um modo geral grande parte dos sistemas desenvolvidos para web
precisa efetuar conexo com banco de dados, utilizar um container IOC para
injeo de dependncias, fazer uso de taglibs na camada de visualizao,
configurar o mapeamento objeto-relacional e ter um controlador para o MVC. E
existe um framework especfico para cada situao destas: Hibernate para
conexo com banco de dados e Mapeamento Objeto-Relacional, o Spring para
MVC e IOC, SiteMesh para definio de layouts e alguma biblioteca para as
taglibs.
Com o Grails a integrao desses frameworks feita de forma
transparente, evitando configuraes desde a edio de arquivos XML at a
criao de estruturas de diretrios (isso para cada framework!).
No decorrer deste artigo sero visualizadas as vantagens de trabalhar
com essa ferramenta. O objetivo final criar uma pequena aplicao web, um
blog, permitindo a criao de posts e comentrios. Tudo ser visto no passo a
passo a seguir.
Arquitetando o Framework
O Grails composto por tecnologias open source j conhecidas no
mercado, como o Hibernate, o Spring e o SiteMesh. Para facilitar ainda
mais o desenvolvimento, como padro, o servidor web Jetty j vem
configurado para qualquer aplicao, alm do HSQLDB, um banco de dados
totalmente escrito em Java. O Grails abstrai toda a complexidade necessria
para manter essa infra-estrutura, focando no desenvolvimento gil e na
conveno por codificao.
Configurao do ambiente
Antes de dar incio ao tutorial, preciso configurar o ambiente para que
os scripts do Grails funcionem corretamente. Efetue o download do Grails em .
Usaremos a verso 1.0.2. Feito o download, descompacte o arquivo para
c:\grails e configure as variveis de ambiente. (No Windows, isso pode ser
feito clicando com o boto direito em Meu Computador > Propriedades >
Avanado >Variveis de Ambiente.) Crie uma varivel GRAILS_HOME cujo
contedo o path de instalao do Grails, como c:\grails. Edite tambm sua
varivel PATH, adicionando o caminho %GRAILS_HOME%\bin. Valide a
configurao no prompt de comando, como pode ser visto na Listagem 1.
Listagem 1. Sada do comando grails no prompt de comando
C:\>grails
Welcome to Grails 1.0.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\grails
No script name specified. Use 'grails help' for more info
O runtime do Groovy j vem embutido na distribuio do Grails, portanto, no
necessria nenhuma instalao ou configuro adicional do Groovy.

Primeiros passos: entendimento da estrutura


Como j citado, a conveno evita demasiadas configuraes, e desta
forma que vamos trabalhar com o Grails. A primeira tarefa ser criar um
projeto. No console digite o comando grails create-app, que solicitar o nome
do projeto. Digite cadastro como exemplo.
Com isso a estrutura do projeto gerada. Digite cd cadastro e examine
seu contedo. A Listagem 2 descreve os diretrios do projeto criados pelo
script.
Listagem 2. Descrio da estrutura do projeto Grails
%PROJECT_HOME%
+ grails-app
+ conf
--->Configurao dos artefatos (data sources,
mapeamentos de URL etc.)
+ hibernate
--->configuraes opcionais do Hibernate
+ spring
--->configuraes opcionais do Spring
+ controllers
--->Localizao dos controladores
+ domain
--->Localizao das classes de domnio
+ i18n
--->Localizao das bundles messages para i18n
+ services
--->Localizao de servios
+ taglib
--->Localizao das taglibs
+ util
--->Classes utilitrias
+ views
--->Localizao das views
+ layouts
--->Localizao dos layouts
+ lib
+ scripts
---> scripts
+ src
+ groovy
--->opcional
+ java
--->opcional
+ test
--->classes de testes gerados
+ web-app
+ WEB-INF
Viso Geral, um perfil da ferramenta
Para contextualizar melhor os utilitrios da ferramenta, vamos testar
tambm outros scripts de configurao, utilizando a seguinte sintaxe grails
[nome-do-comando] (ver Tabela 1).
Comando
Descrio
create-app
Cria uma nova aplicao Grails.
create-controller
Cria um novo controlador.
create-domain-class
Cria uma classe de domnio.
generate-controller
Cria um controlador para uma classe de domnio.
test-app
Roda os testes da aplicao.
run-app
Inicia o servidor web (Jetty) e roda a aplicao
localmente.
generate-all
Cria todos os artefatos para uma classe de domnio.
generate-views
Cria as views para a classe de domnio.
console
Executa o console do Grails com uma interface swing.
Tabela 1. Scripts de configurao

Existem mais alguns comandos que no esto listados, consulte a


documentao do Grails para mais detalhes em .
No diretrio cadastro digite grails run-app. O servidor ser iniciado, alm
de outros servios como o log4j e o Spring.
Em
seguida
abra
o
navegador
web
e
digite
http://localhost:8080/cadastro. Uma tela de boas-vindas ser exibida (Figura
1).

Figura 1. Tela de boas-vindas do Grails


Dessa forma, o servidor web Jetty est pr-configurado para qualquer
aplicao gerada e isso permite efetuar testes sem a necessidade de instalar
um Apache Tomcat, por exemplo.
Controladores
O prximo passo criar um controlador que exibir na tela o texto Ol
Mundo. Na linha de comando digite grails create-controller ola. O arquivo
OlaController.groovy foi gerado pelo script automaticamente no diretrio
cadastro/grails-app/controllers/. Para gerar a sada altere o contedo de
acordo com a Listagem 3.
Listagem 3. Editando um controlador
class OlaController {
def mundo = {render 'Ol mundo!' }
def world = {render 'Hello world!'}
}
Foi adicionado ao controlador ola duas actions, mundo e world, que podem ser
acessadas da seguinte forma:

O localhost o domnio que estamos trabalhando, 8080 a porta do servidor e


cadastro, a nossa aplicao. Ola representa o nosso controlador e
mundo/world so as aes relacionadas a esse controller.
Classes de domnio
Dando continuidade aos scripts, vamos criar uma classe de domnio
chamada usurio. Na linha de comando digite grails create-domain-class
usuario. Edite o arquivo Usuario.groovy criado no diretrio cadastro/grailsapp/domain, conforme Listagem 4.
Listagem 4. Editando a classe de domnio Usuario
class Usuario {
String login
String nome
String senha
}
Definimos uma classe Usuario com trs propriedades: login, nome e senha.
O prximo comando a ser executado efetuar a gerao das views necessrias
para as operaes CRUD (Create, Read, Update e Delete) desta classe.
Views
Na linha de comando digite grails generate-views usuario. Repare que no
diretrio cadastro/grails-app/views/usuario foram criados quatro arquivos:
create.gsp, edit.gsp, list.gsp, e show.gsp. Note que ainda no temos o
controlador para a classe Usuario, que deve possuir as actions para
redirecionar as requisies do cliente. Digite grails generate-controller usuario
na linha de comando. Dessa vez temos um controlador diferente, com todas as
actions necessrias para atender s requisies relacionadas. As actions
adicionadas ao controlador so apresentadas na Listagem 5.
Listagem 5. Controlador Usurio com as actions de CRUD configuradas
class UsuarioController {
def index = { redirect(action:list,params:params) }
// the delete, save and update actions only accept POST requests
def allowedMethods = [delete:'POST', save:'POST', update:'POST']
def list = {
if(!params.max) params.max = 10
[ usuarioList: Usuario.list( params ) ]
}
def show = {
def usuario = Usuario.get( params.id )
if(!usuario) {

flash.message = "Usuario not found with id ${params.id}"


redirect(action:list)
}
else { return [ usuario : usuario ] }
}
def delete = {
def usuario = Usuario.get( params.id )
if(usuario) {
usuario.delete()
flash.message = "Usuario ${params.id} deleted"
redirect(action:list)
}
else {
flash.message = "Usuario not found with id ${params.id}"
redirect(action:list)
}
}
def edit = {
def usuario = Usuario.get( params.id )
if(!usuario) {
flash.message = "Usuario not found with id ${params.id}"
redirect(action:list)
}
else {
return [ usuario : usuario ]
}
}
def update = {
def usuario = Usuario.get( params.id )
if(usuario) {
usuario.properties = params
if(!usuario.hasErrors() && usuario.save()) {
flash.message = "Usuario ${params.id} updated"
redirect(action:show,id:usuario.id)
}
else {
render(view:'edit',model:[usuario:usuario])
}
}
else {
flash.message = "Usuario not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}

def create = {
def usuario = newUsuario()
usuario.properties = params
return ['usuario':usuario]
}
def save = {
def usuario = newUsuario(params)
if(!usuario.hasErrors() && usuario.save()) {
flash.message = "Usuario ${usuario.id} created"
redirect(action:show,id:usuario.id)
}
else {
render(view:'create',model:[usuario:usuario])
}
}
}
Na Listagem 5 a action index redireciona a requisio para list, que elenca
todos os usurios existentes. A action show exibe as informaes de um
usurio a partir de um identificador (ID) que passado como parmetro. O
mesmo para delete e update. J create gera um novo usurio que ser
utilizado por save. Este ltimo recebe os dados da view que, finalmente, so
armazenados. Repare que os arquivos da view possuem o mesmo nome das
actions, fortalecendo o conceito da conveno.
Veja na Figura 2 a representao do modelo MVC (Model, View,
Controller) do Grails, de acordo com o exemplo apresentado.

Figura 2. Funcionamento do MVC no Grails


O
cliente
efetua
uma
requisio
ao
controller
(neste
caso
o
UsuarioController) que, por sua vez, verifica a action pertinente ao pedido.
Utiliza a classe de domnio Usuario para efetuar as tarefas da camada de
modelo, e finalmente encaminha os valores para a view. Nada muito diferente
dos frameworks mais populares no mercado.
No console, reinicie o servidor (CTRL+C ou CTRL+B encerra e grails runapp inicia novamente o Jetty) para realizar a compilao desta nova classe.
Feito isso, o link UsuarioController ser listado na tela principal do projeto.
Clicando nele, a tela de cadastro de usurios aparecer (ver Figura 3).

Figura 3. Tela de cadastro de Usurio


Neste exemplo foi criada uma tela que engloba os componentes de CRUD para
a classe Usuario. Clique em New Usuario e efetue testes inserindo novos
registros, editando e excluindo.
Sempre que o servidor for reiniciado, todas as informaes do HSQLDB sero
perdidas. Para contornar esta caracterstica, edite o arquivo grailsapp/conf/BootStrap.groovy e adicione objetos ao banco de dados no mtodo
init desta classe. Toda vez que a aplicao for iniciada, os objetos sero
armazenados. Ainda neste artigo falaremos sobre o GORM para entender
melhor os detalhes de persistncia no Grails.
Scaffolding
Scaffolding um termo utilizado para representar a gerao de artefatos
necessrios para a criao de uma interface que execute operaes de CRUD.
No exemplo anterior foi utilizada a combinao de alguns scripts para gerar o
CRUD por completo. Se for substitudo todo o contedo do controlador de
Usurio por:
class UsuarioController {
def scaffold = Usuario
}
A interface de CRUD continua funcionando sem problemas. Repare que
automaticamente o Groovy detecta o nome da classe Usuario sem a
necessidade de escrever .class para identificao. Todas as pginas .gsp
criadas pelo script no precisariam ser geradas, o framework cuida disso
atravs da conveno. As URLs utilizadas nas operaes so:

- Lista todos os Usurios;


http://localhost:8080/cadastro/usuario/create - Cadastro de novo
Usurio;

http://localhost:8080/cadastro/usuario/edit/id - Edita um registro a


partir de um ID;

http://localhost:8080/cadastro/usuario/show/id - Exibe um registro a


partir de um ID.
Requests do tipo save, update e delete sero aceitas somente via mtodo
POST.
Por conveno, o mapeamento de URLs configurado de acordo com a Figura
4.

Figura 4. Descritivo do mapeamento de URL no Grails


Como descritivo da Figura 4, o servidor o primeiro item identificado, sendo o
local em que a aplicao est hospedada, acompanhado da porta (segundo
item). O terceiro item a aplicao propriamente dita. O usurio (quarto item)
aparece como o controller que pode estar ou no associado a uma action
(neste caso show, quinto item). Para que o endereo seja referente ao local
que se deseja remeter, deve estar especificado na URL o caminho da action.
Caso contrrio a index, que default, ser chamada.
O GORM no mapeamento Objeto Relacional
O Grails emprega o Hibernate para o mapeamento objeto relacional. Mas voc
no precisar conhecer a API do Hibernate, nem descritores de mapeamento.
Adicionando a configurao por conveno e as facilidades do Groovy, o Grails
cria um novo sistema de persistncia, chamado GORM (Grails Object Relation
Mapping).
Em momento algum do artigo foi descrita a configurao do banco de dados.
Isso porque por default a configurao feita para um banco de dados em
memria, o HSQLDB. Para testes uma boa opo, mas para ambientes de
produo no a escolha ideal. Para mais informaes acesse
http://hsqldb.org/.
Analisando o exemplo da classe Usuario, vamos entender o relacionamento do
Grails com o banco de dados. O nome da tabela ser o mesmo da classe (caso
o nome da classe estiver em formato CamelCase, por exemplo
ComentarioPost, o underscore ser utilizado como separador). A cada classe
gerada, um ID criado implicitamente para representar o identificador nativo
no banco de dados. Tudo isso feito de forma transparente, deixando seu
cdigo mais enxuto.
Para testar as funcionalidades do GORM, abra o console do Groovy atravs da
linha de comando e digite: grails console. Uma interface Swing ser aberta
(ver Figura 5).

Figura 5. Groovy Console


O primeiro teste a ser feito armazenar um usurio no banco de dados. No
console digite as seguintes linhas de comando:
def user = new Usuario(login:'java', nome:'magazine', senha:'java_magazine')
user.save()
Est feito. O objeto user foi criado e armazenado no banco de dados. Observe
que foram desnecessrios quaisquer comandos SQL, abertura e fechamento de
conexes ou interao com outra API. Para recuperar objetos utilize o comando
get:
def user = Usuario.get(1)
println(user.getNome())
---------------------------------sada: magazine
O cdigo abaixo representa uma consulta simples, retornando todos os objetos
do tipo Usuario:
def user = Usuario.list()

A varivel user contm uma lista com todos os usurios, que podem ser
recuperados e ordenados por login:
def user = Usuario.listOrderByLogin()
Mas onde foram definidos esses mtodos da classe Usuario? A resposta : em
lugar nenhum. Estes mtodos so criados dinamicamente e em alguns casos
de acordo com as propriedades da classe. Por exemplo, poderia ser utilizado
listOrderByNome(), que tambm seria um mtodo vlido. Outra forma de
query a Query By Example, no qual passado como parmetro um objeto de
exemplo para ser pesquisado. Imagine que preciso localizar todos os
usurios com o nome java e o login user:
def user = Usuario.find(new Usuario(login:'user', nome:'java'))
Existem diversas outras formas de pesquisa, que podem ser consultadas na
API do projeto: http://grails.org/doc/1.0.x/.
Agora voc j pode criar um blog com o Grails, vamos a ele!
Esta fase prtica do artigo mostrar todo o caminho para criar um blog com
uso do Grails, a partir do que j foi visto. Objetivo: desenvolver um pequeno
blog, que contm somente duas classes, Post e Comentario. Vale lembrar
que um post pode ter muitos comentrios. O Diagrama bem simples,
conforme a Figura 6. Alm disso, vamos definir validaes nos formulrios,
personalizar alguns campos e criar o relacionamento entre as classes.

Figura 6. Diagrama de classes do Blog


Siga os seguintes passos para criar o blog:
1.
Crie um projeto chamado blog;
2.
Com o comando create-domain-class, crie as classes Post e
Comentario;
3.
Edite as classes adicionando as propriedades do diagrama;
4.
Crie os controladores e defina a action para scaffold.
Qualquer dvida nos scripts, leia novamente o tpico Viso Geral, um perfil
da ferramenta. Para o passo 2, na criao de classes de domnio, ler o tpico
Classes de Domnio.
Relacionamento sem crises
Como possvel observar, as classes Post e Comentario possuem uma
relao entre si. O prximo objetivo definir essa ligao.
A propriedade hasMany utilizada para definir uma relao Um para Muitos.
Ela avisa ao Grails que uma instncia da classe X associada a N instncias da
classe Y. No exemplo do blog, a definio seria feita na classe Post,
adicionando a seguinte linha:
static hasMany = [comentarios:Comentario]

Adicione tambm classe Comentario a propriedade belongsTo:


static belongsTo = [post:Post]
Alm disso, criada implicitamente uma propriedade chamada comentarios,
que nada mais do que um objeto java.util.Set que rene todos os objetos
do tipo Comentario relacionados com Post. O GORM tambm adiciona
classe Post o mtodo addComentario(), utilizado para efetuar a adio de
comentrios ao Post. Os tipos de propriedades que definem relacionamentos
so: one-to-one, many-to-one, many-to-many, hasMany e belongsTo,
este ltimo acima citado.
O GrailsScaffold ainda no suporta relacionamentos many-to-many, sendo
necessrio efetuar as configuraes desse tipo de relao manualmente.
Declarao de Constraints, aponte limites
Um post precisa, necessariamente, de um ttulo, um contedo e uma data de
publicao. Caso contrrio, no faria sentido algum uma publicao em um
blog sem essas informaes. O comentrio tambm precisa de um nome, um
e-mail e texto. A URL seria um campo opcional no cadastro. Outras validaes,
alm da garantia de um campo preenchido, saber se ele est correto. Mas
como garantir que o campo e-mail seja preenchido corretamente? Como
identificar uma URL vlida? Algumas dessas validaes j acompanham a API
do Grails, ratificando a informao preenchida nos formulrios.
Um exemplo de validao do campo e-mail seria:
static constraints={email(email:true)}
Faa melhor
Agora que sabemos como criar relacionamentos e declarar constraints, vamos
alterar as classes de domnio para aprimorar o blog j criado (Listagem 6).
Listagem 6. Alterao do blog, adicionando relacionamentos e contraints
class Post {
String titulo
String conteudo
Date data = new Date()
static hasMany = [comentarios:Comentario]
static constraints ={
titulo(blank:false)
conteudo(blank:false)
data(blank:false)
}
String toString(){
return "${this.titulo}"
}
class Comentario {
String nome
String email

String url
String comentario
static belongsTo = [post:Post]
static constraints ={
email(email:true,blank:false)
nome(blank:false)
url(url:true)
comentario(blank:false)
}
String toString(){
return "${this.nome} - ${this.email}"
}
}
As alteraes na classe Post foram feitas para evitar que o ttulo, contedo e a
data de publicao fossem armazenados sem valores. Na classe Comentario
foram feitas constraints mais complexas, na verificao do e-mail e da URL.
Por exemplo, caso o usurio tente escrever ww.com.br no campo URL, o
cadastro no ser concludo.
Dando continuidade ao blog, repare que no geramos as views neste exemplo,
o que temos a gerao automtica das telas via scaffold. Neste ponto, a
limitao muito grande, j que no permitido alterar o layout, os campos
dos formulrios, entre outras variveis. Para melhorar o look-and-feel da
aplicao, gere as views das classes:
grails generate-views Post
grails generate-views Comentario
As telas de cadastro so campos que podem ser sempre aprimorados, de
acordo com a necessidade do projeto. Veja a Figura 7 e repare que o Grails,
por padro, define o formato dos campos dos formulrios segundo os tipos
declarados nas classes de domnio.

Figura 7. Formulrio gerado pelo Grails

No entanto, para o nosso exemplo de elaborao de um blog, os campos


originados no atendem aos objetivos do usurio, pois oferecem uma limitao
de espao e recursos para a constituio do post. O campo Data, com todas as
combos exemplificadas na ilustrao, tambm no algo muito atraente de se
trabalhar em termos de usabilidade. Assim sendo, como otimizar esta tela?
Poderamos inserir um editor WYSIWYG no campo Contedo e um Calendrio
no campo Data, configurando alguns javascripts, e adaptando tudo ao Grails.
Muito trabalho, no? Seria, se no fossem os plugins.
Plugins em ao
O site http://grails.org/Plugins possui uma lista com diversos plugins para a
sua aplicao Grails: testes, RichClient, grficos, web services, performance,
relatrios, entre outros. Como exemplo, vamos utilizar o RichUI em nosso blog.
Na linha de comando, entre no diretrio do projeto (blog) e digite: grails
install-plugin richui. Isso pode levar algum tempo, dependendo da velocidade
de conexo da Internet.
Com o plugin instalado, abra a view create.gsp, localizada em blog/grailsapp/views/post e adicione as seguintes tags no head:
<resource:richTextEditor type="advanced" />
<resource:dateChooser />
J no formulrio, substitua a tag <g:datePicker name="data" value="$
{post?.data}" ></g:datePicker> por <richui:dateChooser name="data"
format="dd/MM/yyyy" />. Da mesma forma, altere o componente do campo
Contedo
para
<richui:richTextEditor
name="conteudo"
value="$
{fieldValue(bean:post,field:'conteudo')}" width="525" />. O resultado ficar
como a Listagem 7.
Listagem 7. Alterao da viewcreate.gsp da classe Post
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main" />
<title>Create Post</title>
<resource:richTextEditor type="advanced" />
<resource:dateChooser />
</head>
<body>
<div class="nav">
<span
class="menuButton"><a
class="home"
href="$
{createLinkTo(dir:'')}">Home</a></span>
<span class="menuButton"><g:link class="list" action="list">Post
List</g:link></span>
</div>
<div class="body">
<h1>Create Post</h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>

<g:hasErrors bean="${post}">
<div class="errors">
<g:renderErrors bean="${post}" as="list" />
</div>
</g:hasErrors>
<g:form action="save" method="post" >
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="data">Data:</label>
</td>
<td
valign="top"
class="value
$
{hasErrors(bean:post,field:'data','errors')}">
<richui:dateChooser name="data" format="dd/MM/yyyy" />
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label for="titulo">Titulo:</label>
</td>
<td
valign="top"
{hasErrors(bean:post,field:'titulo','errors')}">
<input
type="text"
id="titulo"
{fieldValue(bean:post,field:'titulo')}"/>
</td>
</tr>

class="value
name="titulo"

$
value="$

<tr class="prop">
<td valign="top" class="name">
<label for="conteudo">Conteudo:</label>
</td>
<td
valign="top"
class="value
$
{hasErrors(bean:post,field:'conteudo','errors')}">
<richui:richTextEditor
name="conteudo"
value="$
{fieldValue(bean:post,field:'conteudo')}" width="525" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="buttons">
<span
class="button"><input
value="Create" /></span>

class="save"

type="submit"

</div>
</g:form>
</div>
</body>
</html>
Dois novos componentes do plugin RichUI foram adicionados view, o
RichTextEditor e o DateChooser. Os componentes adicionados so
apresentados na Figura 8.

Figura 8. Utilizao do pluginRichUI


As duas faces do layout
Seguindo a filosofia da conveno, os arquivos CSS ficam armazenados no
diretrio web-app/css. Na criao da aplicao, o Grails cria por default um
CSS chamado main.css, que define o layout at aqui trabalhado. Vimos como
criar formulrios para CRUD, mas isso ainda no tudo.
Geralmente existem dois tipos de layouts: aquele que s o administrador do
blog v e outro para o visitante. O administrador da ferramenta ir visualizar
as telas de CRUD. J o visitante, ao acessar o blog, encontra uma tela
direcionada apenas para leitura e interao. Para criar a tela do visitante,
preciso dar origem a dois arquivos, um stylesheet e um gsp.
Se
preferir
um
layout
j
pronto,
entre
no
site
http://www.solucija.com/templates/download/Interactive_Media.zip e baixe
este template indicado no caminho, que ser adaptado ao Grails como exemplo
para este passo a passo:

Descompactar o arquivo baixado;

Copiar as imagens do diretrio /images do template para a pasta


/blog/web-app/images;

Renomear o arquivo main.css da pasta CSS do template para skin.css.


Copiar o arquivo renomeado para /blog/web-app/css.
Com base no template baixado, vamos criar o layout chamado publico.gsp no
diretrio blog/grails-app/views/layouts. Copie o contedo do arquivo
index.html do template e cole em publico.gsp. Efetue as modificaes de
acordo com a Listagem 8.
Listagem 8. Cdigo fonte do layout publico.gsp

<!DOCTYPE
html
PUBLIC
"-//W3C//DTD
XHTML
1.0
Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title><g:layoutTitle default="Grails Blog" /></title>
<link rel="stylesheet" href="${createLinkTo(dir:'css',file:'skin.css')}" />
<link rel="shortcuticon" href="${createLinkTo(dir:'images',file:'favicon.ico')}"
type="image/x-icon" />
<g:layoutHead />
</head>
<body id="home">
<div class="wrap">
<div id="logo">
<h1><a href="." title="Home">GrailsBlog</a></h1>
<p>Tutorial Grails - Java Magazine</p>
</div>
<ul id="nav">
<li><a
class="current"
href="."
accesskey="h"><span
class="akey">H</span>ome</a></li>
<li><a
href="#"
accesskey="a"><span
class="akey">R</span>evista</a></li>
<li><a
href="#"
accesskey="m"><span
class="akey">C</span>ontato</a></li>
<li><a
href="#"
accesskey="r"><span
class="akey">E</span>xemplos</a></li>
<li><a
href="#"
accesskey="c"><span
class="akey">E</span>xercicios</a></li>
</ul>
</div>
<g:layoutBody />
<div id="right">
<h2>Ultimosposts</h2>
<ul>
<g:each in="${postList}" status="i" var="post">
<li><a href="#">${post.titulo}</a></li>
</g:each>
</ul>
<p
id="info">Este
template
foi
baixado
do
site
<a
href="http://www.solucija.com/home/css-templates/"
title="Free
CSS
Templates">Solucija</a></p>
</div>
<div id="footer">
<p><strong>Blog:</strong><a
href=".">Home</a>&middot;
<a
href="#">Revista</a>&middot; <a href="#">Contato</a>&middot; <a
href="#">References</a>&middot; <a href="#">Consulting</a>&middot;
<p><strong>Network:</strong><a href="#">Wordpress</a>&middot;
<a href="#">Blogspot</a>

<p>Design:
<a
href="http://www.solucija.com/">Luka
Cvrk</a>&middot;
Sponsoredby<a
href="http://webpoint.wordpress.com/">B4Contact</a>&middot;
Released
under
a
<a
href="http://creativecommons.org/licenses/by-ncsa/3.0/">Creative Commons Licence</a></p>
</div>
</div>
</body>
</html>
Nesta listagem utilizamos algumas tags do Grails: g:layoutTitle,
g:layoutHead e g:layoutBody. Essas tags vo ser substitudas pelo contedo
de outras views que estiverem utilizando o layout publico.gsp. Para mais
detalhes, veja a Tabela 2.
Tag
g:layoutTitle
g:layoutHead
g:layoutBody
actionSubmit

Descrio
Define o ttulo do layout.
Define o head do layout.
Usada na composio do corpo do layout.
Cria um boto submit para uma action.
Cria um link a partir de atributos. Por exemplo:
createLink
<g:createLink controller=post action=create/>
igual a url /post/create.
formRemote
Form utilizado para executar chamadas Ajax.
Permite
formatar
datas
de
instncias
formatDate
java.util.Date.
Permite formatar nmeros no mesmo padro de
formatNumber
java.text.DecimalFormat.
If / else /elseif / Tags de fluxo de controle.
each
Cria um form que permite o envio de dados do
uploadForm
tipo multipart-form-data, utilizado no upload de
arquivos.
Paginao dos resultados de uma coleo de
paginate
objetos que cria os botes prximo/anterior e
breadcrumbs.
Tabela 2. Lista de tags
Crie um controlador chamado home e defina uma action conforme a Listagem
9.
Listagem 9. Cdigo do HomeController
class HomeController {
def home = {
[ postList: Post.list() ]
}
}

Foi definida a action home com uma varivel chamada postList, que contm
uma lista com todos os objetos do tipo Post. Esses objetos sero utilizados na
view home.gsp, a ser criada no diretrio blog/grails-app/views/home. postList
uma lista, na qual preciso interar e recuperar cada objeto para ser exibido
na view. A tag each do Grails far o trabalho, navegando nessa lista e exibindo
o contedo cadastrado.
Agora vamos analisar o contedo da Listagem 10 para entender melhor o
funcionamento do layout. A tag meta define o layout para esta view; o Grails
procura por um layout chamado publico.gsp, que por conveno, espera que
esteja em blog/grails-app/views/layouts. J a tag g:each responsvel pela
navegao da lista postList, criada no HomeController para que os posts
possam ser exibidos na view. Voltando ao layout publico.gsp, a tag
g:layoutTitle ser substituda por Home quando esta view for exibida. Idem
para a tag layoutBody, que ir gerar o contedo da tag <body>. O resultado
final pode ser visto na Figura 9.
Listagem 10. Cdigo da view home.gsp
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="publico" />
<title>Home</title>
</head>
<body>
<div class="wrap">
<div id="left">
<g:each in="${postList}" status="i" var="post">
<h2>${post.titulo}</h2>
<p>${post.conteudo}</p>
</g:each>
</div>
</div>
</body>

Figura 9. Resultado da aplicao do layout


Configurando o MySQL
At o momento a persistncia dos dados foi feita com o HSQLDB, que por
default vem configurado no Grails. Mas esta no a forma ideal de se
trabalhar, principalmente em um ambiente de produo. Neste exemplo,
vamos utilizar o banco de dados MySQL, que pode ser baixado em
http://dev.mysql.com/downloads/mysql/5.0.html#downloads. Crie um banco
chamado grails_blog. Agora edite o arquivo de configurao blog/grailsapp/conf/DataSource.groovy, permitindo a conexo JDBC com o banco de
dados. Verifique o exemplo na Listagem 11.
Listagem 11. Exemplo de configurao do banco de dados MySQL
dataSource {
pooling = true
dbCreate = "update"
url = "jdbc:mysql://localhost/grails_blog"
driverClassName= "com.mysql.jdbc.Driver"
username = "root"
password = "pass"

}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/grails_blog"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/grails_blog"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/grails_blog"
}
}
}
Observe que existem trs ambientes de desenvolvimento citados no exemplo:
development, test e production. Neste caso configuramos o mesmo banco para
todos os ambientes. O mais correto seria um banco para cada environment.
Outro ponto interessante a migrao automtica do banco de dados,
configurado pelo dbCreate. A migrao ocorre quando alguma alterao feita
nas classes GORM (classes de domnio), permitindo a atualizao das tabelas
do banco de dados em runtime. Existem trs opes: update, create-drop e
create. Os modos create e create-drop removem todos os dados do banco, j o
update simplesmente atualiza as modificaes efetuadas nas classes de
domnio.
Para alm da configurao do DataSource, preciso um driver de conexo
JDBC
para
o
MySQL,
que
pode
ser
obtido
em
http://dev.mysql.com/downloads/connector/j/5.1.html. Descompacte e copie o
JAR mysql-connector-java-<verso>-bin.jar para o diretrio /blog/lib.
Finalizando, edite a classe Post para que o atributo contedo seja do tipo
TEXT. Esta ao permite suportar um nmero maior que 255 caracteres a
representao do tipo String um varchar(255) no banco dados (ver
Listagem 12).

Listagem 12. Alterando o tipo de atributo contedo para TEXT


class Post {
String titulo
String conteudo
Date data = new Date()
static mapping = {
conteudo type:'text'
}
}
O bloco esttico mapping define um mapeamento personalizado para o
GORM, determinando para o atributo conteudo o tipo TEXT (em alguns
bancos de dados o valor CLOB).
Concluso
No ritmo do desenvolvimento gil de software, o Grails , atualmente, a
ferramenta mais indicada para Web porque permite uma codificao mais
sofisticada, o que nos parmetros modernos quer dizer clean. Prtico e
simples, a conveno por configurao uma de suas grandes vantagens,
alm da migrao em tempo real e a arquitetura que possibilita desenvolver
uma aplicao sem a necessidade de instalaes prvias, como servidores de
aplicao web, banco de dados, etc. Oferece tambm a habilidade de ocultar
toda a carga de codificao das diversas ferramentas que ele carrega consigo.
Tudo isso acompanha o Grails e faz com que o recurso se torne ainda mais
inteligente.
Este artigo ofereceu uma viso geral do Grails, alm de uma amostra prtica
de usabilidade com a criao de um blog simples, passo a passo. O domnio do
Grails, como o caso de qualquer framework, vir com a prtica e com
estudos mais aprofundados. No entanto, o desenvolvedor que j tiver
experincia com programao de aplicaes Java ir verificar que o
aprendizado do Grails facilitado pelo seu reuso de grande nmero de
ferramentas e componentes do Java, tanto aqueles que so encapsulados pelo
Grails como o Hibernate, quanto inmeros componentes externos integrados
via plug-ins.
Links
http://www.grails.org
Site oficial
http://www.grailsbrasil.com
Frum Brasileiro
http://grails.org/doc/1.0.x/
Documentao
http://www.grails.org/Plugins
Pgina com a lista de Plugins disponveis
http://www.infoq.com/grails
Site com excelentes informaes sobre Grails
http://www.infoq.com/minibooks/grails;jsessionid=933E681E3185D0558159E
F82C38C2305
Livro gratuito (basta ter registro no site)
http://www.amazon.com/Definitive-Guide-Grails/dp/1590597583
Livro Definitive Guide to Grails

http://www.manning.com/koenig/
Livro Groovy in Action
Box Resumo:
Devman: Veja o que voc vai aprender adicionalmente neste artigo:

O conceito de IOC;

Definio de Conveno por Configurao.


Notas do DevMan:
IOC (Inverso de Controle): um design pattern associado a um conjunto de
tcnicas de programao que inverte o fluxo de controle de um sistema
tradicional. Isto , muda completamente seu modelo de interao. Com uso
deste padro, o container, uma estrutura de software, que fornece a
configurao dos dados necessrios ao sistema, em vez de ser o programador
a executar esta tarefa. Um exemplo clssico a conexo com o banco de
dados, na qual um objeto fornecido por um container como padro para toda
a aplicao. Isso evita trabalho repetido, j que no modelo convencional todo
este processo feito manualmente, sempre que for necessrio se conectar ao
banco de dados.
Conveno por Configurao: O significado desta expresso o de que o
desenvolvedor precisa especificar somente os casos excepcionais da aplicao,
ou seja, a exceo. Por exemplo, uma conveno define que os nomes das
tabelas no banco de dados sejam os mesmos que as suas classes de modelo.
Mas voc deseja fazer algo diferente disso. Nesse caso ocorre a troca da
conveno pela configurao, pois para chegar ao modelo desejado preciso
determinar os cdigos referentes s configuraes.