Framework Demoiselle QuickStart Emerson Oliveira Emerson Saito Luciano Borges Marlon Carvalho Rodrigo Hjort Serge Rehem Sobre o QuickStart ................................................................................................................. v 1. Instalação ........................................................................................................................ 1 1.1. Ambiente recomendado .............................................................................................. 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. Incluindo catálogo remoto ................................................................................. 5 2.3. Entidade de domínio ................................................................................................. 8 2.4. Camada de persistência ............................................................................................. 9 2.5. Camada de negócio ................................................................................................. 10 2.6. Camada de apresentação .......................................................................................... 11 2.7. Executando no servidor ............................................................................................ 13 3. Melhorando a aplicação .................................................................................................... 17 3.1. Exibindo mensagens para o usuário ............................................................................. 17 3.2. Criando regras de validação nos campos ....................................................................... 19 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.4.0-BETA2. Nota Apesar de o Demoiselle Framework 2.4.0-BETA2 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.4.0-BETA2 do Demoiselle Framework e pode diferir significativamente das versões anteriores. v vi Instalação 1.1. Ambiente recomendado 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 7.1.1 www.jboss.org [http://download.jboss.org/ jbossas/7.1/jboss-as-7.1.1.Final/jbossas-7.1.1.Final.zip] 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/manuais-e-tutoriais/tutoriais-da- versao-2/] 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, 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 Para criar esse projeto utilizando a IDE Eclipse, acesse o menu File, New, Other... digite e selecione Maven Project: conforme mostrado na figura abaixo: Na tela seguinte, recomenda-se manter os valores padrões: 3 Capítulo 2. Criação da aplicação 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 Incluindo catálogo remoto 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 , 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.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. Clique no botão Add Remote Catalog...: 5 Capítulo 2. Criação da aplicação Na campo Catalog File coloque este conteúdo: https://oss.sonatype.org/content/ repositories/releases. No campo Description informe: “Nexus”. 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: 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 | | | | | | | | | | | | | | | | | | | | | 6 |-- br |-- gov |-- frameworkdemoiselle |-- sample |-- bookmark |-- business | |-- BookmarkBC.java Incluindo catálogo remoto | | | |-- constant | | | | | | | | | | |-- domain | |-- Bookmark.java | | | |-- exception | | | | | | | | | | |-- message | |-- readme.txt | | | | | | | | | |-- persistence | |-- BookmarkDAO.java |-- util | | | | | | | | | | |-- readme.txt |-- view |-- BookmarkEditMB.java | | | | | | | | | |-- BookmarkListMB.java |-- resources | |-- demoiselle.properties | |-- log4j.properties | | | | | | | | | | | | | | | | | |-- | | | | | | | | | | | | | | | | | | | | | | | | | | | |-- main.xhtml | |-- WEB-INF | |-- beans.xml | |-- faces-config.xml | |-- lib | |-- web.xml |-- test |-- java | |-- br |-- readme.txt |-- readme.txt |-- messages.properties |-- META-INF | |-- beans.xml | |-- persistence.xml |-- ValidationMessages.properties webapp |-|-|-| |-|-|-|-- bookmark_edit.xhtml bookmark_list.xhtml images |-- logo.png index.html index.xhtml menu.xhtml template | | | | | | | | | | | | | | |-- resources |-- demoiselle.properties | | | |-- gov |-- frameworkdemoiselle |-- sample |-- bookmark |-- business |-- BookmarkBCTest.java |-- META-INF |-- beans.xml |-- persistence.xml 7 Capítulo 2. Criação da aplicação 2.3. Entidade de domínio Dentro do pacote br.gov.frameworkdemoiselle.sample.bookmark.domain foi criada 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 implements Serializable { private static final long serialVersionUID = 1L; /* If you are using Glassfish then remove the strategy attribute */ @Id @GeneratedValue(strategy = SEQUENCE) 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; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getLink() { return link; } public void setLink(String link) { this.link = link; } } 8 Camada de persistência 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. 2.4. Camada de persistência Dentro do pacote br.gov.frameworkdemoiselle.sample.bookmark.persistence foi criada 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; } Nota A anotação @PersistenceController trata-se de um estereótipo fornecido pelo Demoiselle Framework 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 (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. Dica 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/ foi criado o arquivo persistence.xml utilizado para armazenar as configurações de acesso ao banco de dados via JPA (conexões controladas por um JPA Provider, ex: Hibernate) ou JTA (conexões controladas pelo Application Server, ex: JBossAS) e, como pode ser observado, o Demoiselle Framework já traz neste arquivo vários exemplos de configurações para os mais distintos Application Servers, como: JBoss AS7, JBoss AS6, GlassFish 3, Tomcat 6 e Tomcat7. O projeto criado pelo arquétipo “demoiselle-jsf-jpa” já vem configurado para usar conexão JPA com o HSQLDB, conforme código abaixo: <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 9 Capítulo 2. Criação da aplicação 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" transaction-type="RESOURCE_LOCAL"> <non-jta-data-source>java:jboss/datasources/ExampleDS</non-jta-data-source> <class>br.gov.frameworkdemoiselle.sample.bookmark.domain.Bookmark</class> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="false" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> </properties> </persistence-unit> </persistence> 2.5. Camada de negócio Dentro do pacote br.gov.frameworkdemoiselle.sample.bookmark.business foi criada 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 load() { 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("Github", "https://github.com/demoiselle")); 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")); } } } O método com a anotação @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. 10 Camada de apresentação Nota A anotação @BusinessController trata-se de um estereótipo fornecido pelo Demoiselle Framework 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. 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. Dica 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. Camada de apresentação Dentro do pacote package br.gov.frameworkdemoiselle.sample.bookmark.view foram criadas as classes BookmarkEditMB e BookmarkListMB, onde a primeira é responsável por controlar as modificações sobre os bookmarks efetuadas pelo usuário e a segunda é responsável por exibir as informações sobre os bookmarks. @ViewController @PreviousView("/bookmark_list.xhtml") public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> { private static final long serialVersionUID = 1L; @Inject private BookmarkBC bookmarkBC; @Override @Transactional public String delete() { this.bookmarkBC.delete(getId()); return getPreviousView(); } @Override @Transactional public String insert() { this.bookmarkBC.insert(getBean()); return getPreviousView(); } @Override @Transactional public String update() { this.bookmarkBC.update(getBean()); return getPreviousView(); } 11 Capítulo 2. Criação da aplicação @Override protected void handleLoad() { setBean(this.bookmarkBC.load(getId())); } } @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 this.bc.findAll(); } @Transactional public String deleteSelection() { boolean delete; for (Iterator<Long> iter = getSelection().keySet().iterator(); iter.hasNext();) { Long id = iter.next(); delete = getSelection().get(id); if (delete) { bc.delete(id); iter.remove(); } } return getPreviousView(); } } 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. 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. 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. 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. 12 Executando no servidor As classes AbstractEditPageBean e AbstractListPageBean fazem parte do código de suporte fornecido pelo Demoiselle Framework (especificamente na extensão JSF). Ao utilizá-las, o desenvolvedor não precisará implementar métodos específicos de navegação para uma tela de cadastro (i.e., do tipo CRUD). Dica 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/ foram criados os arquivos: • bookmark_edit.xhtml - página JSF de cadastro e edição de bookmark; • bookmark_list.xhtml - página JSF de cadastro e edição de bookmark; • index.html - página HTML que redireciona para a página jsf; • index.xhtml - página JSF inicial do sistema; • menu.xhtml - página JSF que monta o menu de navegação. No diretório /src/main/webapp/template foi criado o arquivo: • main.xhtml - página JSF que serve de template referenciada na demais páginas JSF. Nota 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/resources/ podemos observar que foi criado o arquivo de recursos messages.properties. 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. Nota O arquivo de recursos messages.properties armazenará textos no idioma default da aplicação (neste caso, em Português do Brasil). 2.7. Executando no servidor A última etapa consiste em fazer o deploy da Java Web 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 7) e aguarde a inicialização deste. 13 Capítulo 2. Criação da aplicação 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. 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: 14 Executando no servidor Figura 2.1. Página principal da aplicação Bookmark Para cadastrar um novo bookmark basta ir no menu principal: Bookmarks, Novo. Executando-a, será exibida a página a seguir: 15 Capítulo 2. Criação da aplicação Figura 2.2. Tela de cadastro e edição dos dados na aplicação Bookmark 16 Melhorando a aplicação 3.1. 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.bookmark.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.bookmark.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; ... 17 Capítulo 3. Melhorando a apli... @Override public void insert(Bookmark bookmark) { super.insert(bookmark); messageContext.add(InfoMessages.BOOKMARK_INSERT_OK, bookmark.getDescription()); } @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: 18 Criando regras de validação nos campos Figura 3.1. Exibição de mensagens na aplicação Bookmark 3.2. 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.3.0.Final</version> </dependency> </dependencies> 19 Capítulo 3. Melhorando a apli... 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, bastando apenas incluir certas anotações (ex: @NotNull, @Size) nos campos da classe a ser validada. No pacote br.gov.frameworkdemoiselle.sample.bookmark.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 = 30) 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 20 Criando regras de validação nos campos 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: Figura 3.2. 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/. 21 22