QuickStart - Portal Demoiselle

Transcrição

QuickStart - Portal Demoiselle
Framework Demoiselle 2.0
QuickStart
Emerson Saito
Marlon Carvalho
Rodrigo Hjort
Serge Rehem
Sobre o QuickStart ................................................................................................................. v
1. Instalação ........................................................................................................................ 1
1.1. Pré-requisitos .......................................................................................................... 1
1.2. Demoiselle Infra ....................................................................................................... 1
2. Criação da aplicação .......................................................................................................... 3
2.1. Nossa primeira aplicação ............................................................................................ 3
2.2. Construindo o projeto usando um arquétipo Maven ............................................................ 3
2.2.1. Linha de comando ..........................................................................................
2.2.2. Modo assistido com Eclipse ..............................................................................
2.3. Criando a entidade de domínio .....................................................................................
2.4. Implementando a camada de persistência .......................................................................
3
3
8
9
2.5. Implementando a camada de negócio ........................................................................... 10
2.6. Implementando a camada de apresentação .................................................................... 11
2.7. Executando no servidor ............................................................................................ 14
3. Melhorando a aplicação .................................................................................................... 17
3.1. Implementando funcionalidade de edição ....................................................................... 17
3.2. Exibindo mensagens para o usuário ............................................................................. 22
3.3. Criando regras de validação nos campos ....................................................................... 24
iii
iv
Sobre o QuickStart
Este documento é um tutorial do tipo "passo a passo" que visa ilustrar de forma rápida, clara e prática a criação de
uma aplicação simples utilizando o Demoiselle Framework 2.X.
Nota
Apesar de o Demoiselle Framework 2.X ser simples de usar, o desenvolvimento de aplicações
não triviais requer o conhecimento das diversas tecnologias envolvidas na especificação Java
EE, incluindo:
• Linguagem Java
• Servlets, JSP e Tag Libraries
• JavaBeans
• HTML e XML
• Contêineres e Servidores Web
Nota
Esta documentação refere-se à release 2.2.X do Demoiselle Framework e pode diferir
significativamente das versões anteriores.
v
vi
Instalação
1.1. Pré-requisitos
Software
Versão
Site (Download)
Java Development Kit (JDK)
6.0
openjdk.org [http://openjdk.org/]
Apache Maven
2.2
maven.apache.org
[http://
maven.apache.org/docs/2.2.1/releasenotes.html]
Eclipse IDE
3.7
www.eclipse.org
[http://www.eclipse.org/
downloads/packages/release/indigo/r]
m2eclipse plugin
0.12
m2eclipse.sonatype.org
[http://
m2eclipse.sonatype.org/installingm2eclipse.html]
JBoss Application Server
6.0
www.jboss.org
[http://sourceforge.net/
projects/jboss/files/JBoss/
JBoss-6.0.0.Final/jboss-asdistribution-6.0.0.Final.zip/download]
1.2. Demoiselle Infra
Para auxiliar no preparo do ambiente integrado de desenvolvimento utilizado na presente documentação,
recomenda-se a utilização dos pacotes de software fornecidos pelo projeto Demoiselle Infra [http://
demoiselle.sourceforge.net/infra/]. Neste link você encontrará as orientações necessárias para a sua configuração.
Nota
Atualmente são disponibilizados pacotes exclusivamente para a plataforma GNU/Linux e
distribuições baseadas no Debian, tal como Ubuntu.
Se você não utiliza nenhum dos sistemas operacionais citados, terá que baixar e instalar todos os
softwares listados acima. Para auxiliar um pouco o processo, disponibilizamos alguns vídeos
aqui [http://
www.frameworkdemoiselle.gov.br/documentacaodoprojeto/tutoriais/videos/] de demonstração de algumas fases.
1
2
Criação da aplicação
2.1. Nossa primeira aplicação
Para iniciar o uso do Demoiselle Framework 2.X, criaremos uma aplicação Java do tipo Web utilizando o Apache
Maven [http://maven.apache.org/], através do plugin para IDE Eclipse (M2Eclipse) para gerenciar todo o clico de
vida do Projeto, desde a criação até o deploy.
Essa aplicação consistirá em um cadastro simples de bookmarks (links “Favoritos”) e será gerada com o auxílio de
um arquétipo do Maven disponibilizado pelo projeto Demoiselle. Ela será preparada para utilizar as tecnologias de
persistência JPA e de apresentação JSF nas versões mais recentes conforme a especificação Java EE 6.
2.2. Construindo o projeto usando um arquétipo Maven
Importante
O procedimento a seguir pode ser comumente executado de forma visual com o auxílio de um
assistente (i.e., wizard) de dentro da IDE Eclipse, como será demonstrado logo após o modo linha
de comando.
2.2.1. Linha de comando
Para criar a aplicação usando o arquétipo em linha de comando, abra um terminal e execute o comando mvn do
Maven com os argumentos ilustrados a seguir:
mvn archetype:generate \
-DarchetypeGroupId=br.gov.frameworkdemoiselle.archetypes \
-DarchetypeArtifactId=demoiselle-jsf-jpa \
-DarchetypeVersion=2.2.0 \
-DarchetypeRepository=http://demoiselle.sourceforge.net/repository/release/ \
-DgroupId=br.gov.frameworkdemoiselle.sample \
-DartifactId=bookmark \
-Dversion=1.0.0-SNAPSHOT \
-DinteractiveMode=false
2.2.2. Modo assistido com Eclipse
Para criar esse projeto utilizando a IDE Eclipse, acesse o menu File, New, Other... digite e selecione Maven Project:
conforme mostrado na figura abaixo:
3
Capítulo 2. Criação da aplicação
Na tela seguinte, recomenda-se manter os valores "default":
Na tela abaixo, no combo-box chamado Catalog, selecione o item com o nome “Demoiselle” e no campo Filter
digite “JSF” e em seguida selecione o item “demoiselle-jsf-jpa”:
4
Modo assistido com Eclipse
Cuidado
Se as opções anteriores não aparecem, é porque será necessário incluir o catálogo remoto de
arquétipos Maven do Demoiselle. Caso contrário pule o subitem Incluindo catálogo remoto e siga
as demais instruções.
Cuidado
A versão do arquétipo irá variar conforme surjam novas versões do Demoiselle. A imagem deste
guia apresenta a versão 2.0.0, contudo, fique sempre atento para as novas versões do Demoiselle
em nosso site e sempre utilize a versão do arquétipo mais recente.
2.2.2.1. Incluindo catálogo remoto
Ainda na tela criação do novo projeto, clique no botão Configure à direita do combo-box Catalog, para que
apareça a tela de configuração de arquétipos Maven no Eclipse.
5
Capítulo 2. Criação da aplicação
Clique no botão Add Remote Catalog...:
Na campo Catalog
File coloque este conteúdo: http://demoiselle.sourceforge.net/
repository/archetype-catalog.xml. No campo Description informe: “Demoiselle”. Em seguida,
clique no botão Verify... para certificar-se que o conteúdo está correto. Retorne então ao item anterior e siga as
instruções.
Na próxima tela preencha os campos conforme ilustrado a seguir e clique em Finish:
6
Modo assistido com Eclipse
Ao término do processo será criado o projeto bookmark gerenciado pelo Maven e com a seguinte estrutura de
diretórios:
bookmark/
|-- pom.xml
`-- src
|-- main
|
|
|
|
|
|
|
|
|-- java
|
`-- br
|
`-- gov
|
`-- frameworkdemoiselle
|
`-- sample
|
|-- business
|
|-- constant
|
|-- domain
|
|
|
|
|
|
|
|
|
|
|
|-- resources
|
|
|
|
|-- demoiselle.properties
|-- log4j.properties
|
|
|
|
|-- messages.properties
|-- META-INF
|
|
|
|
|
|
|
|
`-- ValidationMessages.properties
|
|
`-- webapp
|-- home.xhtml
|-|-|-|-`--
exception
message
persistence
util
view
|-- beans.xml
`-- persistence.xml
|
|
|-- images
|
`-- logo.png
|
|
|-- index.html
|-- menu.xhtml
|
|-- template
7
Capítulo 2. Criação da aplicação
|
|
|
`-- WEB-INF
`-- main.xhtml
|
|
|-- faces-config.xml
`-- web.xml
`-- test
|-- java
|
|
`-- br
`-- gov
|
`-- frameworkdemoiselle
|
`-- sample
`-- resources
2.3. Criando a entidade de domínio
Dentro do pacote br.gov.frameworkdemoiselle.sample.domain crie a classe Bookmark, a qual será
responsável por representar um objeto de bookmark a ser persistido no banco de dados usando JPA:
@Entity
public class Bookmark {
@Id
@GeneratedValue
private Long id;
@Column
private String description;
@Column
private String link;
public Bookmark() {
super();
}
public Bookmark(String description, String link) {
this.description = description;
this.link = link;
}
}
Nota
Lembre-se de criar os respectivos métodos getter e setter para as propriedades dessa classe.
Os dois construtores da classe Bookmark serão utilizados posteriormente na aplicação. As anotações @Entity,
@Id, @GeneratedValue e @Column são fornecidas pela especificação JPA.
8
Implementando a camada de persistência
2.4. Implementando a camada de persistência
Dentro do pacote br.gov.frameworkdemoiselle.sample.persistence crie a classe BookmarkDAO,
a qual será responsável por manipular os dados:
@PersistenceController
public class BookmarkDAO extends JPACrud<Bookmark, Long> {
private static final long serialVersionUID = 1L;
}
Dica
A anotação @PersistenceController trata-se de um estereótipo fornecido pelo Demoiselle
Framework 2.X para indicar que uma classe será tratada como controlador da camada de
persistência na aplicação.
A classe abstrata JPACrud faz parte do código de suporte fornecido pelo Demoiselle Framework 2.X
(especificamente na extensão JPA). Ao utilizá-la, o desenvolvedor não precisará implementar métodos de
manipulação de uma entidade, tais como busca, listagem, inclusão, alteração e exclusão de registros. Dessa forma,
apenas métodos específicos do caso de uso necessitam ser criados manualmente.
Nota
Recomenda-se usar o sufixo “DAO” nessa classe para indicar que se trata de um objeto de acesso
a dados (i.e., um DAO - Data Access Object).
No diretório /src/main/resources/META-INF/, altere o arquivo persistence.xml com o conteúdo
seguinte:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/
persistence/persistence_2_0.xsd">
<persistence-unit name="bookmark-ds">
<jta-data-source>java:/DefaultDS</jta-data-source>
<class>br.gov.frameworkdemoiselle.sample.domain.Bookmark</class>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.JTATransactionFactory" />
<property name="jta.UserTransaction" value="UserTransaction" />
</properties>
</persistence-unit>
9
Capítulo 2. Criação da aplicação
</persistence>
Este arquivo armazenará as configurações de acesso ao banco de dados via JPA. Neste caso, o gerenciamento
das conexões ficará a cargo do servidor de aplicações (ex: JBoss AS). Será usada a fonte de dados java:/
DefaultDS.
No diretório /src/main/resources/, altere o arquivo demoiselle.properties com o conteúdo seguinte:
frameworkdemoiselle.persistence.unit.name=bookmark-ds
No diretório /src/main/resources/META-INF/, altere o arquivo beans.xml com o conteúdo seguinte:
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_1.xsd">
<alternatives>
<class>br.gov.frameworkdemoiselle.transaction.JTATransaction</class>
</alternatives>
</beans>
2.5. Implementando a camada de negócio
Dentro do pacote br.gov.frameworkdemoiselle.sample.business crie a classe BookmarkBC, a qual
será responsável por gerenciar as regras de negócio referentes aos bookmarks:
@BusinessController
public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> {
private static final long serialVersionUID = 1L;
@Startup
@Transactional
public void startup() {
if (findAll().isEmpty()) {
insert(new Bookmark("Demoiselle Portal", "http://www.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Demoiselle SourceForge", "http://sf.net/projects/demoiselle"));
insert(new Bookmark("Twitter", "http://twitter.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Blog", "http://blog.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Wiki", "http://wiki.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Bug Tracking", "http://tracker.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Forum", "http://forum.frameworkdemoiselle.gov.br"));
insert(new Bookmark("SVN", "http://svn.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Maven", "http://repository.frameworkdemoiselle.gov.br"));
insert(new Bookmark("Downloads", "http://download.frameworkdemoiselle.gov.br"));
}
}
10
Implementando a camada de apresentação
}
O método startup() nessa classe será invocado automaticamente durante a inicialização da aplicação e fará
com que a tabela seja populada com dados iniciais de bookmarks.
Dica
A anotação @BusinessController trata-se de um estereótipo fornecido pelo Demoiselle
Framework 2.X para indicar que uma classe será tratada como controlador da camada de negócio
na aplicação.
A classe DelegateCrud faz parte do código de suporte fornecido pelo Demoiselle Framework 2.0. Ao utilizá-la,
o desenvolvedor não precisará implementar métodos de negócio triviais de uma entidade e tampouco programar a
injeção de dependência entre as camadas de negócio e persistência. Tal injeção será realizada de forma implícita.
Nota
Recomenda-se usar o sufixo “BC” nessa classe para indicar que se trata de um controlador de
negócio (i.e., um BC - Business Controller).
2.6. Implementando a camada de apresentação
Dentro do pacote br.gov.frameworkdemoiselle.sample.view crie a classe BookmarkListMB, a qual
será responsável por exibir as informações sobre os bookmarks para o usuário:
@ViewController
public class BookmarkListMB extends AbstractListPageBean<Bookmark, Long> {
private static final long serialVersionUID = 1L;
@Inject
private BookmarkBC bc;
@Override
protected List<Bookmark> handleResultList() {
return bc.findAll();
}
}
Dica
A anotação @ViewController trata-se de um estereótipo fornecido pelo Demoiselle
Framework para indicar que uma classe será tratada como controlador da camada de
apresentação (i.e., visão) na aplicação.
11
Capítulo 2. Criação da aplicação
A classe AbstractListPageBean faz parte do código de suporte fornecido pelo Demoiselle Framework
(especificamente na extensão JSF). Ao utilizá-la, o desenvolvedor não precisará implementar métodos específicos
de navegação para uma tela de cadastro (i.e., do tipo CRUD).
A anotação @Inject é fornecida pela especificação CDI. Ela realiza a injeção de dependência da camada de
negócio dentro do artefato da camada de apresentação.
Nota
Recomenda-se usar o sufixo “MB” nessa classe para indicar que se trata de um bean gerenciado
do JSF (i.e., um MB - Managed Bean).
No diretório /src/main/webapp/, crie o arquivo bookmark_list.xhtml com o conteúdo seguinte:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">
<ui:define name="body">
<h:form>
<p:dataTable id="list" var="bean" value="#{bookmarkListMB.resultList}">
<f:facet name="header">#{messages['bookmark.list.table.title']}</f:facet>
<p:column style="width:1%;">
<h:selectBooleanCheckbox value="#{bookmarkListMB.selection[bean.id]}" />
</p:column>
<p:column style="width:5%;" sortBy="#{bean.id}">
<f:facet name="header">#{messages['bookmark.label.id']}</f:facet>
<h:outputText value="#{bean.id}" />
</p:column>
<p:column sortBy="#{bean.description}">
<f:facet name="header">#{messages['bookmark.label.description']}</f:facet>
<h:commandLink action="#{bookmarkListMB.getNextView}"
actionListener="#{bookmarkListMB.clear}">
<h:outputText value="#{bean.description}" />
<f:param name="id" value="#{bean.id}" />
</h:commandLink>
</p:column>
<p:column sortBy="#{bean.link}">
<f:facet name="header">#{messages['bookmark.label.link']}</f:facet>
<h:commandLink action="#{bookmarkListMB.getNextView}"
actionListener="#{bookmarkListMB.clear}">
<h:outputText value="#{bean.link}" />
<f:param name="id" value="#{bean.id}" />
</h:commandLink>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
12
Implementando a camada de apresentação
Dica
Nos arquivos XHTML listados neste exemplo foi empregado o framework PrimeFaces [http://
www.primefaces.org/], o qual foi um dos primeiros a oferecer suporte completo à especificação
JSF 2.0.
No diretório /src/main/webapp/, altere o arquivo menu.xhtml com o conteúdo seguinte:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form>
<p:menubar>
<p:submenu label="#{messages['menu.bookmark']}">
<p:menuitem value="#{messages['menu.menuitem.list']}"
url="/bookmark_list.jsf" />
</p:submenu>
<p:submenu>
<f:facet name="label">
<p:menuitem value="#{messages['menu.menuitem.quit']}"
url="http://www.frameworkdemoiselle.gov.br/" />
</f:facet>
</p:submenu>
</p:menubar>
</h:form>
</ui:composition>
No diretório /src/main/resources/, altere o arquivo messages.properties incluindo as linhas a seguir:
bookmark.list.table.title=Lista de Links
bookmark.label.id=ID
bookmark.label.link=Link
bookmark.label.description=Descri\u00E7\u00E3o
bookmark.label=Bookmark
bookmark.alt.id=ID
bookmark.alt.link=Link
bookmark.alt.description=Descri\u00E7\u00E3o
menu.bookmark=Bookmarks
Nota
O arquivo de recursos messages.properties armazenará textos no idioma default da
aplicação (neste caso, em Português do Brasil).
13
Capítulo 2. Criação da aplicação
Dica
Ao invés de manter fixas as descrições em rótulos, links, botões e mensagens em uma aplicação,
recomenda-se parametrizar esses textos em arquivos de recursos. Além de ser considerada boa
prática, essa medida facilita uma posterior internacionalização da aplicação para diversos idiomas.
2.7. Executando no servidor
A última etapa consiste na construção da aplicação Java Web e no respectivo deploy em um servidor de aplicações.
Utilizando a IDE Eclipse, basta clicar com o botão direito no projeto bookmark e acessar o menu Run As, Run
on Server. Em seguida, escolha um servidor compatível com Java EE 6 (ex: JBoss AS 6) e aguarde a inicialização
deste.
Na visão Console você verá as mensagens decorrentes do servidor de aplicações e da inicialização da aplicação
bookmark agora hospedada nele.
Dica
Para executar em modo de depuração, na visão Servers, clique com o botão direito no servidor
desejado e selecione a opção Debug.
Nota
Também é possível efetuar esses passos em linha de comando. Para isso, execute o comando
mvn package, copie o arquivo bookmark.war resultante para a pasta de deploy do servidor
14
Executando no servidor
(ex: JBOSS_HOME/server/default/deploy) e inicie este último através de seu comando
próprio (ex: JBOSS_HOME/bin/run.sh).
Em seguida, abra o navegador Web de sua preferência e acesse o endereço http://localhost:8080/bookmark. Esta
é a página que deverá ser exibida com a aplicação bookmark em funcionamento:
Figura 2.1. Página principal da aplicação Bookmark
15
16
Melhorando a aplicação
3.1. Implementando funcionalidade de edição
Agora que a aplicação inicial já está rodando, iremos aumentar sua complexidade adicionando a funcionalidade de
edição dos registros de bookmark.
Dentro do pacote br.gov.frameworkdemoiselle.sample.view crie a classe BookmarkEditMB, a qual
será responsável por controlar as modificações sobre os bookmarks efetuadas pelo usuário:
@ViewController
@PreviousView("/bookmark_list.xhtml")
public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> {
private static final long serialVersionUID = 1L;
@Inject
private BookmarkBC bc;
@Override
@Transactional
public String delete() {
bc.delete(getId());
return getPreviousView();
}
@Override
@Transactional
public String insert() {
bc.insert(getBean());
return getPreviousView();
}
@Override
@Transactional
public String update() {
bc.update(getBean());
return getPreviousView();
}
@Override
protected void handleLoad() {
setBean(bc.load(getId()));
}
}
17
Capítulo 3. Melhorando a apli...
Dica
A anotação @Transactional trata-se de uma anotação fornecida pelo Demoiselle Framework
para indicar que o método em questão será incluído na sessão transacional. Caso essa anotação
esteja vinculada na classe, todos os seus métodos serão considerados transacionais.
A classe AbstractEditPageBean faz parte do código de suporte fornecido pelo Demoiselle Framework
(especificamente na extensão JSF). Ao utilizá-la, o desenvolvedor não precisará implementar métodos específicos
de navegação para uma tela de cadastro (i.e., do tipo CRUD).
Ainda no pacote br.gov.frameworkdemoiselle.sample.view altere a classe BookmarkListMB:
@ViewController
@NextView("/bookmark_edit.xhtml")
@PreviousView("/bookmark_list.xhtml")
public class BookmarkListMB extends AbstractListPageBean<Bookmark, Long> {
private static final long serialVersionUID = 1L;
@Inject
private BookmarkBC bc;
@Override
protected List<Bookmark> handleResultList() {
return bc.findAll();
}
@Transactional
public String deleteSelection() {
boolean delete = false;
Iterator<Long> iter = getSelection().keySet().iterator();
while (iter.hasNext()) {
Long id = iter.next();
delete = getSelection().get(id);
if (delete) {
bc.delete(id);
iter.remove();
}
}
return getPreviousView();
}
}
A anotação @NextView serve para definir a próxima visão a ser direcionado o fluxo de navegação JSF. De
forma semelhante, a anotação @PreviousView define a visão anterior de um fluxo.
O novo método deleteSelection() servirá para permitir a funcionalidade de exclusão de múltiplas linhas
da tabela. A anotação @Transactional nele faz com que o método seja considerado como transacional,
incluindo-o na respectiva sessão.
No diretório /src/main/webapp/, crie o arquivo bookmark_edit.xhtml com o conteúdo seguinte:
18
Implementando funcionalidade de edição
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">
<ui:define name="body">
<h:form prependId="false">
<p:toolbar>
<p:toolbarGroup align="left">
<p:commandButton value="#{messages['button.save']}"
action="#{bookmarkEditMB.insert}"
rendered="#{!bookmarkEditMB.updateMode}" ajax="false" />
<p:commandButton value="#{messages['button.save']}"
action="#{bookmarkEditMB.update}"
rendered="#{bookmarkEditMB.updateMode}" ajax="false" />
<p:commandButton value="#{messages['button.delete']}"
onclick="confirmation.show()" rendered="#{bookmarkEditMB.updateMode}"
type="button" immediate="true" ajax="false" />
<p:confirmDialog message="#{messages['label.confirm.delete']}"
showEffect="bounce" hideEffect="explode"
header="#{messages['label.dialog.delete']}"
severity="alert" widgetVar="confirmation">
<h:commandButton value="#{messages['button.dialog.yes']}"
action="#{bookmarkEditMB.delete}" immediate="true" ajax="false" />
<h:commandButton value="#{messages['button.dialog.no']}"
onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</p:toolbarGroup>
</p:toolbar>
<br />
<p:fieldset legend="#{messages['bookmark.label']}" toggleable="true"
toggleSpeed="500">
<h:panelGrid id="fields" columns="3">
<h:outputLabel value="#{messages['bookmark.label.id']}: "
for="id" styleClass="text-input" />
<h:outputText id="id" value="#{bookmarkEditMB.bean.id}" />
<p:message for="id" />
<h:outputLabel value="#{messages['bookmark.label.description']}: "
for="description" styleClass="text-input" />
<h:inputText id="description" value="#{bookmarkEditMB.bean.description}"
title="#{messages['bookmark.alt.description']}" />
<p:message for="description" />
<h:outputLabel value="#{messages['bookmark.label.link']}: "
for="link" styleClass="text-input" />
<h:inputText id="link" value="#{bookmarkEditMB.bean.link}"
title="#{messages['bookmark.alt.link']}" />
<p:message for="link" />
</h:panelGrid>
</p:fieldset>
</h:form>
</ui:define>
</ui:composition>
Ainda no diretório /src/main/webapp/, modifique o arquivo bookmark_list.xhtml com o conteúdo
seguinte:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
19
Capítulo 3. Melhorando a apli...
xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">
<ui:define name="body">
<h:form>
<p:toolbar>
<p:toolbarGroup align="left">
<p:commandButton title="#{messages['button.new']}"
image="ui-icon-document" action="#{bookmarkListMB.getNextView}"
actionListener="#{bookmarkListMB.clear}" ajax="false" />
<p:commandButton title="#{messages['button.delete']}"
image="ui-icon-trash" onclick="confirmation.show()" type="button"
immediate="true" ajax="false" />
<p:confirmDialog message="#{messages['label.confirm.delete']}"
showEffect="bounce" hideEffect="explode"
header="#{messages['label.dialog.alert']}!"
severity="alert" widgetVar="confirmation">
<h:commandButton value="#{messages['button.dialog.yes']}"
action="#{bookmarkListMB.deleteSelection}"
actionListener="#{bookmarkListMB.clear}" />
<h:commandButton value="#{messages['button.dialog.no']}"
onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</p:toolbarGroup>
</p:toolbar>
<p:dataTable id="list" var="bean" value="#{bookmarkListMB.resultList}">
<f:facet name="header">#{messages['bookmark.list.table.title']}</f:facet>
<p:column style="width:1%;">
<h:selectBooleanCheckbox value="#{bookmarkListMB.selection[bean.id]}" />
</p:column>
<p:column style="width:5%;" sortBy="#{bean.id}">
<f:facet name="header">#{messages['bookmark.label.id']}</f:facet>
<h:outputText value="#{bean.id}" />
</p:column>
<p:column sortBy="#{bean.description}">
<f:facet name="header">#{messages['bookmark.label.description']}</f:facet>
<h:commandLink action="#{bookmarkListMB.getNextView}"
actionListener="#{bookmarkListMB.clear}">
<h:outputText value="#{bean.description}" />
<f:param name="id" value="#{bean.id}" />
</h:commandLink>
</p:column>
<p:column sortBy="#{bean.link}">
<f:facet name="header">#{messages['bookmark.label.link']}</f:facet>
<h:commandLink action="#{bookmarkListMB.getNextView}"
actionListener="#{bookmarkListMB.clear}">
<h:outputText value="#{bean.link}" />
<f:param name="id" value="#{bean.id}" />
</h:commandLink>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
No diretório /src/main/webapp/, altere o arquivo menu.xhtml conforme o conteúdo seguinte:
20
Implementando funcionalidade de edição
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form>
<p:menubar>
<p:submenu label="#{messages['menu.bookmark']}">
<p:menuitem value="#{messages['menu.menuitem.new']}"
url="/bookmark_edit.jsf" />
<p:menuitem value="#{messages['menu.menuitem.list']}"
url="/bookmark_list.jsf" />
</p:submenu>
<p:submenu>
<f:facet name="label">
<p:menuitem value="#{messages['menu.menuitem.quit']}"
url="http://www.frameworkdemoiselle.gov.br/" />
</f:facet>
</p:submenu>
</p:menubar>
</h:form>
</ui:composition>
Tendo feito todas essas alterações, reconstrua o projeto Java e faça novo deploy no servidor de aplicações.
Ao acessar a aplicação bookmark pelo browser, verá que agora existe uma opção nova no menu principal:
Bookmarks, Novo. Executando-a, será exibida a página a seguir:
Figura 3.1. Edição dos dados na aplicação Bookmark
21
Capítulo 3. Melhorando a apli...
3.2. Exibindo mensagens para o usuário
Uma vez que o objetivo principal da aplicação foi concluído (i.e., listagem e edição de bookmarks), veremos algumas
funcionalidades adicionais fornecidas pelo Demoiselle Framework, iniciando pelo tratamento de mensagens.
Dentro do pacote br.gov.frameworkdemoiselle.sample.message crie a interface InfoMessages, a
qual servirá para armazenar mensagens informativas a serem exibidas ao usuário:
public interface InfoMessages {
final Message BOOKMARK_DELETE_OK = new DefaultMessage("{bookmark-delete-ok}");
final Message BOOKMARK_INSERT_OK = new DefaultMessage("{bookmark-insert-ok}");
final Message BOOKMARK_UPDATE_OK = new DefaultMessage("{bookmark-update-ok}");
}
Nota
A unidade básica de manipulação de mensagens no Demoiselle Framework é a interface
Message. Ou seja, basta que esta última seja implementada na aplicação para que o contexto de
mensagens possa manipulá-la. A classe DefaultMessage é oferecida como implementação
padrão dessa interface.
No
exemplo
em
questão,
o
texto
das
mensagens
será
recuperado
do
arquivo
de
recursos
messages.properties previamente criado no diretório /src/main/resources/. Para isso, adicione as
seguintes linhas nesse arquivo:
bookmark-delete-ok=Bookmark exclu\u00EDdo\: {0}
bookmark-insert-ok=Bookmark inserido: {0}
bookmark-update-ok=Bookmark atualizado: {0}
Dentro do pacote br.gov.frameworkdemoiselle.sample.business altere a classe BookmarkBC
incluindo os trechos de código indicados a seguir:
@BusinessController
public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> {
@Inject
private MessageContext messageContext;
...
@Override
public void insert(Bookmark bookmark) {
super.insert(bookmark);
messageContext.add(InfoMessages.BOOKMARK_INSERT_OK,
bookmark.getDescription());
}
22
Exibindo mensagens para o usuário
@Override
public void update(Bookmark bookmark) {
super.update(bookmark);
messageContext.add(InfoMessages.BOOKMARK_UPDATE_OK,
bookmark.getDescription());
}
@Override
public void delete(Long id) {
super.delete(id);
messageContext.add(InfoMessages.BOOKMARK_DELETE_OK, id);
}
}
No ponto contendo @Inject será injetado via CDI o contexto de mensagens presente na aplicação, ou seja,
uma instância da interface MessageContext que poderá ser utilizada em qualquer método nessa classe.
Aqui os métodos insert(), update() e delete() da classe DelegateCrud são sobrescritos para
permitir com que o contexto de mensagens seja manipulado em cada invocação destes. O método add() de
MessageContext faz com que a mensagem passada como parâmetro seja adicionada ao contexto, que ao
final será exibida para o usuário na camada de apresentação.
Nota
O contexto de mensagens, representado pela interface MessageContext, é capaz de
armazenar diversas mensagens em uma mesma requisição. Ele não é restrito à aplicações do
tipo Web, isto é, pode ser usado também para aplicações do tipo desktop (i.e., Swing).
Ao término das modificações propostas até aqui, reconstrua o projeto Java e faça novo deploy no servidor de
aplicações. Acesse a aplicação bookmark e efetue inclusões, modificações e exclusões de bookmarks. As
mensagens informativas devem aparecer em caixas de mensagens na tela, tal como ilustrado a seguir:
23
Capítulo 3. Melhorando a apli...
Figura 3.2. Exibição de mensagens na aplicação Bookmark
3.3. Criando regras de validação nos campos
Sendo aderente à especificação Java EE 6, o Demoiselle Framework recomenda e faz uso do mecanismo de
validação provido pela especificação JSR-303 (Bean Validation) [http://jcp.org/en/jsr/detail?id=303].
A fim de testarmos mais essa funcionalidade, utilizaremos a implementação de validação Hibernate Validator. Para
tal, abra o arquivo pom.xml do projeto bookmark e inclua nele a seguinte dependência:
<dependencies>
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
</dependencies>
Nota
O objetivo dessa abordagem de validação é auxiliar na criação de restrições diretamente nas
entidades de domínio. Tais restrições serão utilizadas de forma conjunta nas camadas de
persistência e apresentação da aplicação. A vantagem é que elas são facilmente configuráveis,
24
Criando regras de validação nos campos
bastando apenas incluir certas anotações (ex: @NotNull, @Size) nos campos da classe a ser
validada.
No pacote br.gov.frameworkdemoiselle.sample.domain altere a entidade de domínio Bookmark
incluindo as anotações de validação nos campos description e link conforme ilustrado a seguir:
@Entity
public class Bookmark {
@Id
@GeneratedValue
private Long id;
@Column
@NotNull
@Size(min = 1, max = 20)
private String description;
@Column
@NotNull
@NotBlank
@Size(max = 255)
@URL
private String link;
...
}
No campo description, a anotação @NotNull serve para impedir que o valor nulo seja atribuído a ele.
Já a anotação @Size restringe a quantidade mínima e máxima de caracteres no campo.
No campo link mais restrições são aplicadas. Além de não permitir o valor nulo (com @NotNull) e estipular
o comprimento máximo de 255 caracteres (com @Size), o campo não pode ficar vazio (com @NotBlank) e
seu conteúdo deve ser um endereço de Internet válido (com @URL).
Dica
Validações de campos específicos para a comunidade brasileira são oferecidos pelo componente
Demoiselle Validation. Com ele, as seguintes anotações podem ser aplicadas nas classes de
domínio: @Cep, @Cnpj, @Cpf, @InscricaoEstadual e @PisPasep.
Assim que você efetuar as modificações, reconstrua o projeto Java e faça novo deploy no servidor de aplicações.
Acesse a aplicação bookmark e, na tela de edição de bookmarks, deixe vazios os campos no formulário e clique
em Salvar. Tente também preencher um endereço de Internet inválido no campo Link. Caixas de erro com as
mensagens referentes as validações devem aparecer ao lado de cada campo, tal como ilustrado:
25
Capítulo 3. Melhorando a apli...
Figura 3.3. Validação de campos na aplicação Bookmark
Dica
As mensagens exibidas na tela durante a validação estão contidas no arquivo de recursos
ValidationMessages.properties presente no diretório /src/main/resources/.
26

Documentos relacionados