Beruflich Dokumente
Kultur Dokumente
dos
com
este
com
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.
http://localhost:8080/cadastro/usuario/create - Cadastro de novo
Usurio;
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.
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.
<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.
<!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>·
<a
href="#">Revista</a>· <a href="#">Contato</a>· <a
href="#">References</a>· <a href="#">Consulting</a>·
<p><strong>Network:</strong><a href="#">Wordpress</a>·
<a href="#">Blogspot</a>
<p>Design:
<a
href="http://www.solucija.com/">Luka
Cvrk</a>·
Sponsoredby<a
href="http://webpoint.wordpress.com/">B4Contact</a>·
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>
}
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).
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;