Você está na página 1de 24

Grails: mais inspiração, menos transpiração

Programação web em Java nunca foi tão fácil


Convenção por configuração. 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 país por ser uma
ferramenta que oferece velocidade na programação de aplicações para Web.

Para que serve:


Lidar com o Grails serve como diferencial para elaborar desde projetos
complexos aos mais simples. E significa também estar integrado a uma
tendência de mercado cuja exigência é de alta capacidade de dinamismo. O
uso do Grails como solução faz com que o programador possa otimizar seu
tempo e distribuí-lo melhor em tarefas qualitativas.

Em que situação 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 soluções e prazos. Sua grande
utilidade é a de ditar ao trabalho um ritmo que supera os recursos tradicionais,
justamente por ter códigos mais integrados e inteligíveis.

Grails: mais inspiração, menos transpiração – Resumo DevMan:


O conjunto de facilitadores que compõe o Grails torna o cotidiano dos
desenvolvedores menos sacrificado no que diz respeito ao desgaste com
complexidade de detalhes e codificações. Para detalhar melhor seu uso, este
artigo traz um demonstrativo prático com a criação de um blog construído com
emprego da ferramenta.

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


nova geração de frameworks MVC para linguagens dinâmicas, como o Rails (do
Ruby) ou o Django (do Python). Os “agilistas” trazem mandamentos curiosos
de filosofia de programação, como KISS - Keep It Simple, Stupid! (mantenha
simples, estúpido!), DRY - Don’t Repeat Yourself (não se repita), You Ain’t
Gonna Need It (você não vai precisar disso) ou Build Less (desenvolva menos),
entre muitos outros que pregam um modelo de trabalho com menos
transpiração e mais inspiração.

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 convenção por configuração (troca da configuração explícita, ex.: via
código ou descritores, por convenções).
O Grails imprime um jeito simples de programar e faz com que o profissional
esteja mais livre para se dedicar às regras de negócio. Tudo leva a crer que
este não seja apenas mais um concorrente no espaço já bastante saturado de
frameworks web para Java.

Mas qual é a diferença entre o Grails e um framework MVC qualquer?


De um modo geral grande parte dos sistemas desenvolvidos para web
precisa efetuar conexão com banco de dados, utilizar um container IOC para
injeção de dependências, fazer uso de taglibs na camada de visualização,
configurar o mapeamento objeto-relacional e ter um controlador para o MVC. E
existe um framework específico para cada situação destas: Hibernate para
conexão com banco de dados e Mapeamento Objeto-Relacional, o Spring para
MVC e IOC, SiteMesh para definição de layouts e alguma biblioteca para as
taglibs.
Com o Grails a integração desses frameworks é feita de forma
transparente, evitando configurações desde a edição de arquivos XML até a
criação de estruturas de diretórios (isso para cada framework!).
No decorrer deste artigo serão visualizadas as vantagens de trabalhar
com essa ferramenta. O objetivo final é criar uma pequena aplicação web, um
blog, permitindo a criação de posts e comentários. 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 padrão, o servidor web Jetty já vem
configurado para qualquer aplicação, além do HSQLDB, um banco de dados
totalmente escrito em Java. O Grails abstrai toda a complexidade necessária
para manter essa infra-estrutura, focando no desenvolvimento ágil e na
convenção por codificação.

Configuração do ambiente
Antes de dar início ao tutorial, é preciso configurar o ambiente para que
os scripts do Grails funcionem corretamente. Efetue o download do Grails em .
Usaremos a versão 1.0.2. Feito o download, descompacte o arquivo para
c:\grails e configure as variáveis de ambiente. (No Windows, isso pode ser
feito clicando com o botão direito em Meu Computador > Propriedades >
Avançado >Variáveis de Ambiente.) Crie uma variável GRAILS_HOME cujo
conteúdo é o path de instalação do Grails, como c:\grails. Edite também sua
variável PATH, adicionando o caminho %GRAILS_HOME%\bin. Valide a
configuração no prompt de comando, como pode ser visto na Listagem 1.

Listagem 1. Saída 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 distribuição do Grails, portanto, não
é necessária nenhuma instalação ou configurção adicional do Groovy.
Primeiros passos: entendimento da estrutura
Como já citado, a convenção evita demasiadas configurações, 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 conteúdo. A Listagem 2 descreve os diretórios do projeto criados pelo
script.
Listagem 2. Descrição da estrutura do projeto Grails
%PROJECT_HOME%
+ grails-app
+ conf --->Configuração dos artefatos (data sources,
mapeamentos de URL etc.)
+ hibernate --->configurações opcionais do Hibernate
+ spring --->configurações opcionais do Spring
+ controllers --->Localização dos controladores
+ domain --->Localização das classes de domínio
+ i18n --->Localização das bundles messages para i18n
+ services --->Localização de serviços
+ taglib --->Localização das taglibs
+ util --->Classes utilitárias
+ views --->Localização das views
+ layouts --->Localização dos layouts
+ lib
+ scripts ---> scripts
+ src
+ groovy --->opcional
+ java --->opcional
+ test --->classes de testes gerados
+ web-app
+ WEB-INF

Visão Geral, um perfil da ferramenta


Para contextualizar melhor os utilitários da ferramenta, vamos testar
também outros scripts de configuração, utilizando a seguinte sintaxe grails
[nome-do-comando] (ver Tabela 1).
Comando Descrição
create-app Cria uma nova aplicação Grails.
create-controller Cria um novo controlador.
create-domain-class Cria uma classe de domínio.
generate-controller Cria um controlador para uma classe de domínio.
test-app Roda os testes da aplicação.
run-app Inicia o servidor web (Jetty) e roda a aplicação
localmente.
generate-all Cria todos os artefatos para uma classe de domínio.
generate-views Cria as views para a classe de domínio.
console Executa o console do Grails com uma interface swing.
Tabela 1. Scripts de configuração
Existem mais alguns comandos que não estão listados, consulte a
documentação do Grails para mais detalhes em .
No diretório cadastro digite grails run-app. O servidor será iniciado, além
de outros serviços 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


aplicação gerada e isso permite efetuar testes sem a necessidade de instalar
um Apache Tomcat, por exemplo.

Controladores
O próximo 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 diretório
cadastro/grails-app/controllers/. Para gerar a saída altere o conteúdo 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 domínio que estamos trabalhando, 8080 é a porta do servidor e
cadastro, a nossa aplicação. “Ola” representa o nosso controlador e
mundo/world são as ações relacionadas a esse controller.

Classes de domínio
Dando continuidade aos scripts, vamos criar uma classe de domínio
chamada usuário. Na linha de comando digite grails create-domain-class
usuario. Edite o arquivo Usuario.groovy criado no diretório cadastro/grails-
app/domain, conforme Listagem 4.

Listagem 4. Editando a classe de domínio Usuario


class Usuario {
String login
String nome
String senha
}

Definimos uma classe Usuario com três propriedades: login, nome e senha.
O próximo comando a ser executado efetuará a geração das views necessárias
para as operações CRUD (Create, Read, Update e Delete) desta classe.

Views
Na linha de comando digite grails generate-views usuario. Repare que no
diretório cadastro/grails-app/views/usuario foram criados quatro arquivos:
create.gsp, edit.gsp, list.gsp, e show.gsp. Note que ainda não temos o
controlador para a classe Usuario, que deve possuir as actions para
redirecionar as requisições do cliente. Digite grails generate-controller usuario
na linha de comando. Dessa vez temos um controlador diferente, com todas as
actions necessárias para atender às requisições relacionadas. As actions
adicionadas ao controlador são apresentadas na Listagem 5.

Listagem 5. Controlador Usuário 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 requisição para list, que elenca
todos os usuários existentes. A action show exibe as informações de um
usuário a partir de um identificador (ID) que é passado como parâmetro. O
mesmo para delete e update. Já create gera um novo usuário que será
utilizado por save. Este último recebe os dados da view que, finalmente, são
armazenados. Repare que os arquivos da view possuem o mesmo nome das
actions, fortalecendo o conceito da convenção.
Veja na Figura 2 a representação 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 requisição ao controller (neste caso o
UsuarioController) que, por sua vez, verifica a action pertinente ao pedido.
Utiliza a classe de domínio 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 run-
app inicia novamente o Jetty) para realizar a compilação desta nova classe.
Feito isso, o link UsuarioController será listado na tela principal do projeto.
Clicando nele, a tela de cadastro de usuários aparecerá (ver Figura 3).
Figura 3. Tela de cadastro de Usuário
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 informações do HSQLDB serão


perdidas. Para contornar esta característica, edite o arquivo grails-
app/conf/BootStrap.groovy e adicione objetos ao banco de dados no método
init desta classe. Toda vez que a aplicação for iniciada, os objetos serão
armazenados. Ainda neste artigo falaremos sobre o GORM para entender
melhor os detalhes de persistência no Grails.

Scaffolding
Scaffolding é um termo utilizado para representar a geração de artefatos
necessários para a criação de uma interface que execute operações de CRUD.
No exemplo anterior foi utilizada a combinação de alguns scripts para gerar o
CRUD por completo. Se for substituído todo o conteúdo do controlador de
Usuário 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 identificação. Todas as páginas .gsp
criadas pelo script não precisariam ser geradas, o framework cuida disso
através da convenção. As URLs utilizadas nas operações são:
· - Lista todos os Usuários;
· http://localhost:8080/cadastro/usuario/create - Cadastro de novo
Usuário;
· 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 serão aceitas somente via método
POST.
Por convenção, 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 aplicação está hospedada, acompanhado da porta (segundo
item). O terceiro item é a aplicação propriamente dita. O usuário (quarto item)
aparece como o controller que pode estar ou não associado a uma action
(neste caso show, quinto item). Para que o endereço seja referente ao local
que se deseja remeter, deve estar especificado na URL o caminho da action.
Caso contrário a index, que é default, será “chamada”.
O GORM no mapeamento Objeto Relacional
O Grails emprega o Hibernate para o mapeamento objeto relacional. Mas você
não precisará conhecer a API do Hibernate, nem descritores de mapeamento.
Adicionando a configuração por convenção e as facilidades do Groovy, o Grails
cria um novo sistema de persistência, chamado GORM (Grails Object Relation
Mapping).
Em momento algum do artigo foi descrita a configuração do banco de dados.
Isso porque por default a configuração é feita para um banco de dados em
memória, o HSQLDB. Para testes é uma boa opção, mas para ambientes de
produção não é a escolha ideal. Para mais informações 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
código mais enxuto.
Para testar as funcionalidades do GORM, abra o console do Groovy através 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 usuário 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 desnecessários quaisquer comandos SQL, abertura e fechamento de
conexões ou interação com outra API. Para recuperar objetos utilize o comando
get:

def user = Usuario.get(1)


println(user.getNome())
----------------------------------
saída: magazine

O código abaixo representa uma consulta simples, retornando todos os objetos


do tipo Usuario:

def user = Usuario.list()


A variável user contém uma lista com todos os usuários, que podem ser
recuperados e ordenados por login:

def user = Usuario.listOrderByLogin()


Mas onde foram definidos esses métodos da classe Usuario? A resposta é: em
lugar nenhum. Estes métodos são criados dinamicamente e em alguns casos
de acordo com as propriedades da classe. Por exemplo, poderia ser utilizado
listOrderByNome(), que também seria um método válido. Outra forma de
query é a Query By Example, no qual é passado como parâmetro um objeto de
exemplo para ser pesquisado. Imagine que é preciso localizar todos os
usuários 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 prática 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 contém somente duas classes, Post e Comentario. Vale lembrar
que um post pode ter muitos comentários. O Diagrama é bem simples,
conforme a Figura 6. Além disso, vamos definir validações nos formulários,
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 dúvida nos scripts, leia novamente o tópico Visão Geral, um perfil
da ferramenta. Para o passo 2, na criação de classes de domínio, ler o tópico
Classes de Domínio.
Relacionamento sem crises
Como é possível observar, as classes Post e Comentario possuem uma
relação entre si. O próximo objetivo é definir essa ligação.
A propriedade hasMany é utilizada para definir uma relação “Um para Muitos”.
Ela avisa ao Grails que uma instância da classe X é associada a N instâncias da
classe Y. No exemplo do blog, a definição seria feita na classe Post,
adicionando a seguinte linha:

static hasMany = [comentarios:Comentario]


Adicione também à classe Comentario a propriedade belongsTo:

static belongsTo = [post:Post]


Além disso, é criada implicitamente uma propriedade chamada comentarios,
que nada mais é do que um objeto java.util.Set que reúne todos os objetos
do tipo Comentario relacionados com Post. O GORM também adiciona à
classe Post o método addComentario(), utilizado para efetuar a adição de
comentários ao Post. Os tipos de propriedades que definem relacionamentos
são: one-to-one, many-to-one, many-to-many, hasMany e belongsTo,
este último acima citado.
O GrailsScaffold ainda não suporta relacionamentos many-to-many, sendo
necessário efetuar as configurações desse tipo de relação manualmente.
Declaração de Constraints, aponte limites
Um post precisa, necessariamente, de um título, um conteúdo e uma data de
publicação. Caso contrário, não faria sentido algum uma publicação em um
blog sem essas informações. O comentário também precisa de um nome, um
e-mail e texto. A URL seria um campo opcional no cadastro. Outras validações,
além 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 válida? Algumas dessas validações já acompanham a API
do Grails, ratificando a informação preenchida nos formulários.
Um exemplo de validação do campo e-mail seria:

static constraints={email(email:true)}

Faça melhor
Agora que sabemos como criar relacionamentos e declarar constraints, vamos
alterar as classes de domínio para aprimorar o blog já criado (Listagem 6).

Listagem 6. Alteração 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 alterações na classe Post foram feitas para evitar que o título, conteúdo e a
data de publicação fossem armazenados sem valores. Na classe Comentario
foram feitas constraints mais complexas, na verificação do e-mail e da URL.
Por exemplo, caso o usuário tente escrever “ww.com.br” no campo URL, o
cadastro não será concluído.

Dando continuidade ao blog, repare que não geramos as views neste exemplo,
o que temos é a geração automática das telas via scaffold. Neste ponto, a
limitação é muito grande, já que não é permitido alterar o layout, os campos
dos formulários, entre outras variáveis. Para melhorar o look-and-feel da
aplicação, gere as views das classes:

grails generate-views Post


grails generate-views Comentario

As telas de cadastro são campos que podem ser sempre aprimorados, de


acordo com a necessidade do projeto. Veja a Figura 7 e repare que o Grails,
por padrão, define o formato dos campos dos formulários segundo os tipos
declarados nas classes de domínio.

Figura 7. Formulário gerado pelo Grails


No entanto, para o nosso exemplo de elaboração de um blog, os campos
originados não atendem aos objetivos do usuário, pois oferecem uma limitação
de espaço e recursos para a constituição do post. O campo Data, com todas as
combos exemplificadas na ilustração, também não é algo muito atraente de se
trabalhar em termos de usabilidade. Assim sendo, como otimizar esta tela?
Poderíamos inserir um editor WYSIWYG no campo Conteúdo e um Calendário
no campo Data, configurando alguns javascripts, e adaptando tudo ao Grails.
Muito trabalho, não? Seria, se não fossem os plugins.
Plugins em ação
O site http://grails.org/Plugins possui uma lista com diversos plugins para a
sua aplicação Grails: testes, RichClient, gráficos, web services, performance,
relatórios, entre outros. Como exemplo, vamos utilizar o RichUI em nosso blog.
Na linha de comando, entre no diretório do projeto (blog) e digite: grails
install-plugin richui. Isso pode levar algum tempo, dependendo da velocidade
de conexão da Internet.
Com o plugin instalado, abra a view create.gsp, localizada em blog/grails-
app/views/post e adicione as seguintes tags no head:

<resource:richTextEditor type="advanced" />


<resource:dateChooser />

Já no formulário, 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
Conteúdo para <richui:richTextEditor name="conteudo" value="$
{fieldValue(bean:post,field:'conteudo')}" width="525" />. O resultado ficará
como a Listagem 7.

Listagem 7. Alteração 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" class="value $
{hasErrors(bean:post,field:'titulo','errors')}">
<input type="text" id="titulo" name="titulo" value="$
{fieldValue(bean:post,field:'titulo')}"/>
</td>
</tr>

<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 class="save" type="submit"
value="Create" /></span>
</div>
</g:form>
</div>
</body>
</html>

Dois novos componentes do plugin RichUI foram adicionados à view, o


RichTextEditor e o DateChooser. Os componentes adicionados são
apresentados na Figura 8.

Figura 8. Utilização do pluginRichUI

As duas faces do layout


Seguindo a filosofia da convenção, os arquivos CSS ficam armazenados no
diretório web-app/css. Na criação da aplicação, o Grails cria por default um
CSS chamado main.css, que define o layout até aqui trabalhado. Vimos como
criar formulários para CRUD, mas isso ainda não é 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 interação. 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 diretório /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
diretório blog/grails-app/views/layouts. Copie o conteúdo do arquivo
index.html do template e cole em publico.gsp. Efetue as modificações de
acordo com a Listagem 8.

Listagem 8. Código 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-nc-
sa/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 vão ser substituídas pelo conteúdo
de outras views que estiverem utilizando o layout publico.gsp. Para mais
detalhes, veja a Tabela 2.

Tag Descrição
g:layoutTitle Define o título do layout.
g:layoutHead Define o head do layout.
g:layoutBody Usada na composição do corpo do layout.
actionSubmit Cria um botão 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 instâncias
formatDate
java.util.Date.
Permite formatar números no mesmo padrão 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.
Paginação dos resultados de uma coleção de
paginate objetos que cria os botões “próximo/anterior” e
“breadcrumbs”.
Tabela 2. Lista de tags
Crie um controlador chamado home e defina uma action conforme a Listagem
9.

Listagem 9. Código do HomeController


class HomeController {

def home = {
[ postList: Post.list() ]

}
}
Foi definida a action home com uma variável chamada postList, que contém
uma lista com todos os objetos do tipo Post. Esses objetos serão utilizados na
view home.gsp, a ser criada no diretório 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 conteúdo cadastrado.
Agora vamos analisar o conteúdo 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 convenção, espera que
esteja em blog/grails-app/views/layouts. Já a tag g:each é responsável pela
navegação 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á substituída por Home quando esta view for exibida. Idem
para a tag layoutBody, que irá gerar o conteúdo da tag <body>. O resultado
final pode ser visto na Figura 9.

Listagem 10. Código 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 aplicação do layout
Configurando o MySQL
Até o momento a persistência dos dados foi feita com o HSQLDB, que por
default vem configurado no Grails. Mas esta não é a forma ideal de se
trabalhar, principalmente em um ambiente de produção. 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 configuração blog/grails-
app/conf/DataSource.groovy, permitindo a conexão JDBC com o banco de
dados. Verifique o exemplo na Listagem 11.

Listagem 11. Exemplo de configuração 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 três 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 migração automática do banco de dados,
configurado pelo dbCreate. A migração ocorre quando alguma alteração é feita
nas classes GORM (classes de domínio), permitindo a atualização das tabelas
do banco de dados em runtime. Existem três opções: update, create-drop e
create. Os modos create e create-drop removem todos os dados do banco, já o
update simplesmente atualiza as modificações efetuadas nas classes de
domínio.
Para além da configuração do DataSource, é preciso um driver de conexão
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-<versão>-bin.jar para o diretório /blog/lib.
Finalizando, edite a classe Post para que o atributo conteúdo seja do tipo
TEXT. Esta ação permite suportar um número maior que 255 caracteres – a
representação do tipo String é um varchar(255) no banco dados (ver
Listagem 12).
Listagem 12. Alterando o tipo de atributo conteúdo para TEXT
class Post {
String titulo
String conteudo
Date data = new Date()
static mapping = {
conteudo type:'text'
}
}
O bloco estático “mapping” define um mapeamento personalizado para o
GORM, determinando para o atributo conteudo o tipo TEXT (em alguns
bancos de dados o valor é CLOB).
Conclusão
No ritmo do desenvolvimento ágil de software, o Grails é, atualmente, a
ferramenta mais indicada para Web porque permite uma codificação mais
sofisticada, o que nos parâmetros modernos quer dizer clean. Prático e
simples, a convenção por configuração é uma de suas grandes vantagens,
além da migração em tempo real e a arquitetura que possibilita desenvolver
uma aplicação sem a necessidade de instalações prévias, como servidores de
aplicação web, banco de dados, etc. Oferece também a habilidade de ocultar
toda a carga de codificação 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 visão geral do Grails, além de uma amostra prática
de usabilidade com a criação de um blog simples, passo a passo. O domínio do
Grails, como é o caso de qualquer framework, virá com a prática e com
estudos mais aprofundados. No entanto, o desenvolvedor que já tiver
experiência com programação de aplicações Java irá verificar que o
aprendizado do Grails é facilitado pelo seu reuso de grande número de
ferramentas e componentes do Java, tanto aqueles que são encapsulados pelo
Grails como o Hibernate, quanto inúmeros componentes externos integrados
via plug-ins.

Links
http://www.grails.org
Site oficial
http://www.grailsbrasil.com
Fórum Brasileiro
http://grails.org/doc/1.0.x/
Documentação
http://www.grails.org/Plugins
Página com a lista de Plugins disponíveis
http://www.infoq.com/grails
Site com excelentes informações 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;
· Definição de Convenção por Configuração.
Notas do DevMan:
IOC (Inversão de Controle): É um design pattern associado a um conjunto de
técnicas de programação que inverte o fluxo de controle de um sistema
tradicional. Isto é, muda completamente seu modelo de interação. Com uso
deste padrão, é o container, uma estrutura de software, que fornece a
configuração dos dados necessários ao sistema, em vez de ser o programador
a executar esta tarefa. Um exemplo clássico é a conexão com o banco de
dados, na qual um objeto é fornecido por um container como padrão para toda
a aplicação. Isso evita trabalho repetido, já que no modelo convencional todo
este processo é feito manualmente, sempre que for necessário se conectar ao
banco de dados.
Convenção por Configuração: O significado desta expressão é o de que o
desenvolvedor precisa especificar somente os casos excepcionais da aplicação,
ou seja, a exceção. Por exemplo, uma convenção 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
convenção pela configuração, pois para chegar ao modelo desejado é preciso
determinar os códigos referentes às configurações.

Você também pode gostar