NetBeans Visual Web JSF

NetBeans Visual Web JSF

Integrado com Spring 2.5, JPA e Hibernate Criando uma aplicação passo a passo com Visual Web JavaServer Faces, Spring 2.5 e Hibernate utilizando JPA O Visual Web JavaServer Faces é um editor visual de páginas JavaServer Faces, no estilo WYSIWYG (What You See Is What You Get), baseado no Java Studio Creator IDE, da Sun Microsystems. Adaptado como pacote para o NetBeans IDE 5.5, ao qual podia ser instalado separadamente, foi incorporado na versão 6.0 do NetBeans IDE, tornando-se parte de seu assistente de criação de páginas Web. Como seu desenvolvimento é baseado em componentes visuais arrastáveis, com pouco código, o desenvolvedor pode criar páginas totalmente funcionais, integradas com banco de dados através do uso de JDBC. Embora o Visual Web JSF possa ser utilizado para desenvolver aplicações integradas a outros frameworks, não há assistentes ou componentes visuais que o façam até o momento. Neste artigo vamos usar esta ferramenta, examinando alguns de seus recursos, guiando o leitor na construção de uma aplicação integrada ao Spring Framework 2.5, Java Persistence API e Hibernate.

Visual Web JavaServer Faces na prática O projeto utilizado neste artigo está baseado em apenas uma entidade, que é o suficiente para ilustrar como integrar o Visual Web JSF com os demais frameworks. Esta aplicação fará um CRUD (Create, Read, Update and Delete) de uma tabela proposta de contatos e seu resultado final, em execução, será similar a Figura 1.

Figura 1. Tela do exemplo em funcionamento

Preparando o ambiente de desenvolvimento Para acompanhar este artigo, será necessário a instalação do NetBeans (6.0 ou superior) em conjunto com um servidor suportado de aplicações Web Java. O NetBeans pode ser baixado em seu pacote específico para o desenvolvimento Web (Web & Java EE), ao qual já inclui o GlassFish V2 e o Apache Tomcat 6, os quais são pré-configurados na instalação. Outros servidores poderão ser usados, desde que sejam suportados pelo NetBeans. Neste caso, será preciso adicioná-lo manualmente, através do menu Tools>Servers>Add Server. Para o exemplo, será utilizado o Apache Tomcat que já vem integrado ao programa. Os plugins do Spring Framework e Hibernate para o NetBeans O NetBeans possui um plugin para trabalhar com o Spring Framework, automatizando tarefas como a geração dos arquivos e a adição das bibliotecas exigidas pelo Spring. No NetBeans 6.0, Através do menu Tools>Plugins selecione “Spring Framework Support” em Available Plugins e clique em Install (Figura 2). Após a instalação, poderá ser necessário reiniciar o NetBeans. No NetBeans 6.1 não é preciso fazer nada: o suporte ao Spring já vem instalado por padrão, sendo que o plugin mudou de nome para “Spring Web MVC Support”.

Figura 2. Seleção do plugin Spring Framework Support para instalação Criando o projeto e adicionando suporte ao Spring Com o NetBeans aberto, selecione File>New Project>Web>Web Application. Preencha o Project Name, ex.: “VisualWebJM”. Altere Server para Apache Tomcat 6.0.14, conforme a Figura 3.

em Servlet URL Mapping. Criando o projeto de exemplo Na terceira etapa. conforme ilustrado na Figura 4. Figura 4. mude para “*.Figura 3. selecione o framework Visual Web JavaServer Faces. Seleção dos frameworks que serão usados no projeto .faces”. Altere o nome do pacote em Default Java Package e.

será necessário adicionar as bibliotecas citadas anteriormente.jar. email varchar(50).5. Para adicioná-las.0 ou superior). . hibernate-validator.3.5). PRIMARY KEY id_contato(id) ). Após criar o banco de dados no MySQL e sua respectiva tabela (veja o quadro “Executando instruções SQL pelo NetBeans”). em seguida. foi preciso adicionar as bibliotecas do Hibernate. A Listagem 1 mostra o script para a criação da tabela que será usada no exemplo. Clique no botão Add JAR/Folder e selecione as bibliotecas faltantes.5 Library. e com o botão direito do mouse sobre Databases selecione New Connection. acesse Tools>Libraries>Libraries e selecione spring-framework-2. O banco de dados utilizado e seu driver JDBC Utilizaremos como banco de dados o MySQL. foram separadas as bibliotecas.1) e javassist. nascimento date.1. que estão separadas em três downloads diferentes: jboss-archive-browsing. Além dos plugins.2. que já possui o driver JDBC préconfigurado com o NetBeans IDE (versão 6. Script da criação da tabela no MySQL CREATE TABLE contato( id int NOT NULL auto_increment.jar (Hibernate EntityManager 3.5>Add Library. com o nome de usuário e senha (veja Figura 5). adicione o suporte ao Spring Framework através do botão direito do mouse sobre Libraries. em Add Library>spring-framework-2. Em Basic setting>Name selecione MySQL (Connector/J driver). volte ao NetBeans. Listagem 1. nome varchar(50). Algumas bibliotecas podem estar faltando. que devem ser baixadas no site oficial do Hibernate (veja a seção “Links”) No NetBeans IDE 6. na janela Services. Preencha Database URL com o acesso ao seu banco de dados e. telefone varchar(20).jar (Hibernate Core 3. sendo necessário instalar os plugins Hibernate Support e Hibernate 3.Após a criação do projeto.2. O plugin que fora instalado possui as bibliotecas do Hibernate e do Spring. No momento em que escrevo.

Verifique a saída na janela Output>SQL Command 1 Execution. em Data Source. para o exemplo. uma vez que mais adiante esta informação será substituída. Criando a entidade Contato Sem aprofundar na JPA. Selecione a conexão que foi criada anteriormente em Database Connection e confirme. digite o script da tabela na janela SQL Command 1 e clique no botão Run SQL(Ctrl+Shift+E). Dê um nome qualquer em JNDI Name. teremos a tabela contato sendo exibida na coluna Available Tables. Para exibir a tabela criada em Services>“Sua conexão”>Tables. será necessário adicionar o driver JDBC do MySQL ao projeto. clique novamente com o direito e selecione Refresh. observe que em Class Names>Class Name há o nome da classe que será criada. siga os passos descritos a seguir: 1. ex. 3. vá com o direito do mouse sobre a conexão criada e selecione Connect. Através da janela Services. Para isso.: javamagazine. ilustrada pela Figura 7. chamada de Contato. Selecione-a e clique em Add > para colocá-la em Selected Tables para avançar. Figura 6. Altere o nome do pacote. que no caso é Contato. . Por fim. Acesse File>New File>Persistence>Entity Classes from Database e. Na última etapa do assistente. A caixa de diálogo será semelhante à Figura 6. selecione New Data Source.entity. Com o direito do mouse sobre Tables>Execute Command. selecione Add Library>MySQL JDBC Driver>Add Library. 2. Criação de um novo Data Source Retornando ao assistente. teremos apenas uma entidade. em Databases. 4. na segunda etapa do assistente. Criação de uma nova conexão com o banco de dados Executando instruções SQL pelo NetBeans É possível gerar a tabela pelo NetBeans executando o script da Listagem 1.Figura 5. que será criada por um assistente do NetBeans. Com o botão direito do mouse em Libraries.

. mantenha o criado para o exemplo e confirme no botão Create. Figura 8. incluindo a anotação @GeneratedValue.U. Para o Data Source. Você pode determinar qual nome quer dar à sua unidade de persistência. o assistente exibe o botão Create Persistence Unit. que adicionou suas bibliotecas ao projeto. ex.Figura 7. que não é adicionado pelo assistente.: JavaMagazine. Criando uma entidade persistente Por ser a primeira entidade persistente do projeto. ao qual exibirá a caixa de diálogo da Figura 8. toda entidade deve pertencer a uma P. Incluímos manualmente esta anotação. pois desejamos que o valor da chave-primária seja criado de forma automática. Criando uma Unidade de Persistência Uma Persistence Unit (Unidade de Persistência) é um conjunto de configurações de persistência da JPA. Acione este botão. A Listagem 2 exibe o POJO. O provedor JPA utilizado será o Hibernate. que já está selecionado graças ao plugin Spring Framework.

xml <?xml version="1. @Column(name = "email") private String email..Serializable.autodetection" value="class. //getters and setters } Ao criar a entidade. Código da entidade Contato package javamagazine.IDENTITY) @Column(name = "id".io. Configuração do arquivo persistence.mysql. Altere-o como mostrado na Listagem 3. @Column(name = "telefone") private String telefone.url" value="jdbc:mysql://localhost/javamagazine" /> <property name="hibernate.connection. nullable = false) private Integer id. @Column(name = "nome") private String nome.hibernate.util.username" value="root" /> .Date.archive.persistence.> <persistence-unit name="JavaMagazine"> <provider>org.Driver" /> <property name="hibernate.connection.entity.MySQLInnoDBDialect"/> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hibernate.dialect.HibernatePersistence</provider> <properties> <property name="hibernate.ejb.xml.*.Listagem 2.DATE) private Date nascimento. import javax.0" encoding="UTF-8"?> <persistence .driver_class" value="com.connection.dialect" value="org. @Column(name = "nascimento") @Temporal(TemporalType..jdbc.show_sql" value="true" /> <property name="hibernate. import java. import java. @Id @GeneratedValue(strategy = GenerationType. Listagem 3. hbm" /> <property name="hibernate. o NetBeans também adicionou o arquivo de configuração da persistência ao seu projeto em Configuration Files>persistence. @Entity @Table(name = "contato") public class Contato implements Serializable { private static final long serialVersionUID = 1L.

entityManager. A classe DAO package javamagazine.connection.transaction. javamagazine.annotation.entity.password" value="" /> </properties> </persistence-unit> </persistence> Acessando os dados Embora o Spring sempre tenha suportado o trabalho com persistência de dados por outras tecnologias de mapeamento objeto-relacional (ORM). tal tarefa sempre necessitou do conhecimento específico da biblioteca de persistência em questão. } @Transactional(readOnly = false) public void delete(Contato contato) { if (!this.contains(contato)) { contato = this.List. evitando o uso de “fábricas” de objetos para isolar as implementações das interfaces.persist(contato). return (Contato) contato. Preencha o nome da classe ContatoDaoImp e o pacote javamagazine.entityManager.util. Listagem 4.merge(contato).<property name="hibernate. . Sobre o projeto.entityManager = entityManager. import import import import java.persistence. A JPA melhora a portabilidade das aplicações.springframework.dao. Altere a classe como mostra a Listagem 4. Além disso.entityManager. @Transactional(readOnly = true) public class ContatoDaoImp { private EntityManager entityManager.dao.*. pois várias ferramentas ORM implementam sua API padronizada. a injeção de dependências permite implementar o padrão DAO sem a necessidade de muitas classes.*. org. } protected EntityManager getEntityManager() { return entityManager.Contato. @PersistenceContext public void setEntityManager(EntityManager entityManager) { this. } @Transactional(readOnly = false) public Contato save(Contato contato) { this. com o direito selecione New>Java Class. javax.

createQuery("SELECT c FROM Contato c"). o Spring injeta um EntityManager no serviço quando for instanciado.merge(contato). incluindo transações. Extraindo a interface da classe ContatoDaoImp A Listagem 3 contém o código do nosso DAO. com o direito sobre ela. Esta anotação pode ser colocada no atributo ou método setter. } public List<Contato> findAll() { Query q = this. o Spring examinará todos os beans que contenham esta anotação.} this.getResultList(). acione Refactor>Extract Interface.entityManager. Com a anotação @PersistenceContext. só que sem a necessidade de um contêiner EJB para isso. return q. a aplicação adquire uma das grandes vantagens que um EJB tem. Selecione as opções mostradas na Figura 9 e clique no botão Refactor. Declarar a transação com o atributo readOnly=true (somente leitura) indica que esta só fará leituras de dados. Capacitado pelo Spring de efetuar commit ou rollback nas transações de forma transparente e no momento adequado. com a adição das anotações referentes ao Spring Framework. O atributo propagation indica o tipo de propagação da transação.entityManager. Figura 9. . você possui um comportamento similar ao oferecido pelo EJB 3. e com o elemento <tx:annotation-driven /> no contexto da aplicação.remove(contato). só que rodando num contêiner web simples e leve como o Tomcat. } } Após a alteração da classe. a classe fará o controle transacional. Graças a esta injeção. } @Transactional(readOnly = false) public void update(Contato contato) { this. Com @Transactional.entityManager.

independente de provedor. É neste arquivo que temos as configurações de acesso ao banco de dados pela JPA para realizar as operações de persistência. em Projects.LocalContainerEntityManagerFactoryBean: <bean id="entityManagerFactory" class="org.jpa. Neste caso.orm. Altere para applicationContext em File Name na segunda etapa. Selecione Spring Framework>Spring Beans Context file e prossiga. utilizamos a factory org.xml. é necessário declarar um gerenciador. o Spring precisará ser configurado para que o acesso a dados se apóie nos recursos do framework. A declaração da classe é ilustrada no trecho a seguir: <bean id="transactionManager" .Configurando o Spring Com a criação do DAO. a classe org.springframework. Figura 10. selecione o Namespace exibido na Figura 10 e confirme.orm. Resta configurar os beans que serão utilizados para que o Spring possa gerir as transações e informá-lo da classe que será usada para a injeção de dependências.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="JavaMagazine" /> </bean> Com a propriedade de LocalContainerEntityManagerFactoryBean especificamos o nome da persistence unit do arquivo persistence. Seleção do namespace do arquivo de configuração do Spring Framework O assistente adicionará automaticamente os Namespaces utilizados pelo Spring em seu arquivo de configuração. Para a execução em ambientes Java EE. Para a configuração do controle transacional em uma aplicação baseada no Spring. Na terceira etapa do assistente.jpa.jpa.orm. Com o botão direito sobre WEB-INF.springframework.springframework. acesse New>Other.JpaTransactionManager é utilizada para trabalhar com a JPA.

jpa. O elemento <tx:annotation-driven> foi utilizado porque configuramos as transações no DAO com a anotação @Transactional. Para que não tenhamos que fazer injeção de dependência do EntityManager em todos os nossos DAOs.support. Note que o bean contatoDao não contém referência ao bean entityManagerFactory. O JpaTransactionManager é recomendado para aplicações que utilizam apenas uma EntityManager.orm.springframework.class="org.> <!-. Listagem 5.Responsavel pela injecao do EntityManager nas classes que usam a anotacao @PersistenceContext --> <bean class="org.support.EntityManagerFactory para colaborar com EntityManager produzido pela fábrica.springframework. para conduzir transações.0" encoding="UTF-8"?> <beans .springframework.ContatoDaoImp"> .JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-.dao.support.PersistenceAnnotationBeanPostProces sor" /> A Listagem 5 exibe o arquivo de configuração do Spring que será utilizado pela aplicação.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> JpaTransactionManager precisa de qualquer implementação de javax.springframework.jpa.jpa.jpa.Marcacao de transacoes atraves de anotacoes --> <tx:annotation-driven /> <bean id="contatoDao" class="javamagazine.PersistenceAnnotationBeanPostProces sor" /> <!-.orm..orm.jpa.Responsavel pela gestao das transacoes --> <bean id="transactionManager" class="org.Responsavel pela gestao das entidades --> <bean id="entityManagerFactory" class="org.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="JavaMagazine" /> </bean> <!-.springframework.PersistenceAnnotationBeanPostProc essor.orm..orm. que procura todas as classes anotadas com @PersistenceContext e faz a injeção de dependência automaticamente: <bean class="org.springframework.jpa.persistence. Configuração do Spring para o exemplo <?xml version="1. utilizamos a classe org.orm.

OpenEntityManagerInViewInterceptor "> . o arquivo applicationContext.support. podendo executar qualquer código antes e depois da mesma. Embora o exemplo deste artigo não trate de relacionamentos.springframework.</bean> </beans> Para iniciar o Spring com a aplicação. utilizamos um padrão chamado de "Open Session in View". muito menos sobre a estratégia Lazy. é importante entender que.web. Caso queira expandir mais adiante o exemplo. Isso significa que temos de deixar a sessão do Hibernate aberta ou inicializar todos os relacionamentos antes de renderizar a página. conforme o trecho mostrado: <bean name="openEntityManagerInViewInterceptor" class="org. que deve ser configurado em web.springframework. O Spring possui um filtro que trabalha sobre este conceito.springframework. o Spring também fornece mais configurações.OpenEntityManagerInViewFilter </filter-class> </filter> Como alguns desenvolvedores podem não gostar do uso de Filtros para esta tarefa. criando um padrão "Open EntityManager in View".jpa. A diferença entre os dois é que o interceptador roda no contêiner Spring e é configurado em applicationContext.xml. conforme o trecho mostrado: <filter> <filter-name>openEntityManager</filter-name> <filter-class> org.context. Quando um servidor web recebe uma requisição. esta é automaticamente filtrada pelo Interceptador/Filtro. é importante comentar que.jpa. em alguns casos você poderá utilizar a estratégia Lazy. criando relacionamentos para outras entidades. Ambas opções podem causar problemas importantes de consumo de recursos do SGBD (como conexões) ou de desempenho. Para evitar estes problemas.support.xml: <listener> <listener-class> org. Quando a aplicação termina de ler os dados desta estratégia.ContextLoaderListener </listener-class> </listener> Para trabalhar com JPA. o Spring também possui um interceptador que faz o mesmo processo. no Hibernate. como estamos trabalhando com o Hibernate.orm. lançando uma exceção do tipo LazyInitializationException caso alguma associação da entidade seja lida posteriormente.xml. a sessão é fechada. teríamos que criar um padrão semelhante para EntityManager1[1].orm. no uso de JPA.xml deverá ser registrado por um listener em web.

através da injeção no atributo contatoDao. Este controle de transações será administrado pelo Spring.xml. public class ContatoController { private ContatoDao contatoDao. import java. iremos utilizar o Filtro.OpenEntityManagerInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>openEntityManager</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> O controle de acesso O Facade ContatoController (veja Listagem 7) é a classe responsável pela lógica de negócios. Configurando o Spring Framework em web.xml</param-value> </context-param> <filter> <filter-name>openEntityManager</filter-name> <filter-class> org. como exemplo.Contato.support.entity.jpa. . </bean> Para este artigo.springframework. import javamagazine.xml <listener> <listener-class> org. public ContatoDao getContatoDao() { return contatoDao. Listagem 6.. Esta classe terá a injeção do Spring no managed bean para trabalhar com o JavaServer Faces.ContatoDao.dao.List.controller.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*. A classe ContatoController package javamagazine. import javamagazine. delegando chamadas à camada de acesso a dados e controle transacional.springframework.orm.context..util.web.. Listagem 7. onde na Listagem 6 é exibida toda a configuração que deve ser adicionada em web.

Listagem 8.jsf.xml.xml.springframework.findAll(). Esta injeção é indicada com a sintaxe #{bean nomeado no Spring}.jsf.} public void setContatoDao(ContatoDao contatoDao) { this..DelegatingVariableResolver </variable-resolver> </application> A classe DelegatingVariableResolver é capaz de resolver beans declarados no Spring e injetá-los no managed bean de forma transparente.> <application> <variable-resolver> org.springframework.update(contato).save(contato). é necessário adicionar o elemento variable-resolver. para chamar a classe DelegatingVariableResolver do framework: <application> <variable-resolver> org. } public void salvar(Contato contato) { contatoDao. no arquivo facesconfig. Configuração da integração do JSF com o Spring <faces-config .web. Isso indica que nosso managed bean deixa de ser responsável por instanciar o objeto que irá utilizar e passa a recebê-lo do Spring. a mesma utilizada pelo JSF para injetar dependências nos managed beans. } public List todos() { return contatoDao. } public void atualizar(Contato contato) { contatoDao. } } Integrando o Visual Web JSF ao Spring Para configurar o Spring de modo que ele possibilite se integrar ao JavaServer Faces.delete(contato). } public void excluir(Contato contato) { contatoDao.DelegatingVariableResolver </variable-resolver> </application> . A Listagem 8 mostra o managed bean ContatoController configurado em faces-config.web..contatoDao = contatoDao.

Através do arquivo Page1. de com.controller.ContatoController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>contatoDao</property-name> <value>#{contatoDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>SessionBean1</managed-bean-name> <managed-bean-class>javamagazine.appbase. em Design. Este método retorna qualquer atributo armazenado em um escopo de sessão .Page1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ApplicationBean1</managed-bean-name> <managed-bean-class>javamagazine. e não acesso direto ao banco de dados.ApplicationBean1</managed-beanclass> <managed-bean-scope>application</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>RequestBean1</managed-bean-name> <managed-bean-class>javamagazine. e seus métodos através do Design do Visual Web JSF. os dados foram convertidos em Array.RequestBean1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-config> Acessando o Facade pelo Visual Web JSF Para acessarmos a classe ContatoController.SessionBean1</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Page1</managed-bean-name> <managed-bean-class>javamagazine. serão necessários alguns passos a mais do que comumente seria se estivéssemos trabalhando com instruções SQL diretamente. Para o caso.web.<managed-bean> <managed-bean-name>ContatoController</managed-bean-name> <managed-bean-class> javamagazine. vamos abrir a classe SessionBean1 para fazer esta integração. uma classe da biblioteca do Visual Web. através do uso direto de JDBC disponível pela ferramenta. Como o padrão do Visual Web JSF é trafegar em um escopo de sessão (veja no quadro “Os escopos de uma aplicação com Visual Web JSF”). será preciso converter os dados para que estes se tornem acessíveis visualmente pelo Visual Web JSF.jsp. dê um duplo clique em Navigation>SessionBean1.ui. Como estamos usando JPA. O acesso à classe ContatoController será feito através do método getBean().rave. tornando-os acessíveis ao componente Table visualmente.FacesBean.sun.

. } . Ao salvar as alterações. vá ao menu Build>Build Main Project para compilar as classes. Claro que o campo escolhido é o id do contato.web. haverá a necessidade de armazenar a identificação do contato selecionado no componente Table. todosContatos(). public Contato[] getContatos() { return contatos.sob o nome especificado. import import import import com. Para finalizar. adicione no método void init() uma chamada ao método todosContatos(). protected ContatoController getContatoController() { return (ContatoController) getBean("ContatoController").faces. javamagazine. O método init() inicializa o que houver em seu escopo antes do carregamento do aplicativo e antes de componentes gerenciados serem inicializados (ver Listagem 9).ContatoController.. Em outras palavras. } public void setContatos(Contato[] contatos) { this. que será armazenado em sessão para resgatarmos no momento de salvarmos os dados alterados.AbstractSessionBean. como no caso de ContatoController.Contato. nas alterações desta classe.FacesException.appbase.. Desta forma.controller.entity. javax. será possível manipular os métodos existentes na classe determinada. public class SessionBean1 extends AbstractSessionBean { // omitidos por não haver alterações.rave. } //array de Contato private Contato[] contatos. a página do aplicativo obterá os dados encontrados no banco. public void init() { // omitidos por não haver alterações.. Alterações na classe SessionBean1 package javamagazine. } // omitidos por não haver alterações.ui.. Esse passo é importante para que torne essas alterações na classe acessíveis visualmente pelo Design.sun. javamagazine.contatos = contatos. Listagem 9. Como temos apenas um formulário para manipular os contatos (cadastro e alteração).. podendo preencher a tabela com os contatos existentes antes desta ser renderizada.

contendo objetos com um escopo de aplicação. que possui escopo de requisição. há casos que precisamos de um tempo maior. Quando a aplicação é executada em um servidor. onde há uma comunicação com o servidor para que este possa saber que o usuário ainda permanece naquele estado. public Integer getId() { return id. A Figura 11 representa o resultado final do desenho da página.toArray(new Contato[0]). } } Os escopos de uma aplicação com Visual Web JSF Ao criar um projeto com o framework Visual Web JSF. todos().id = id. } //transporta em sessão o ID selecionado para atualização private Integer id = null. perceberá que o Visual Web JSF é semelhante.//carrega todos os contatos public void todosContatos() { contatos = (Contato[]) getContatoController(). A classe ApplicationBean1 possui uma estrutura parecida com SessionBean1. Enquanto o usuário permanecer na página comprando. Visual Studio . os dados trafegam em um escopo de sessão. a menos que seja alterado nas configurações do NetBeans. } public void setId(Integer id) { this. . que dura enquanto a “sessão” estiver aberta (ou o navegador). É evidente que isso pode ser alterado. Este é um escopo de sessão. são colocadas três classes que representam os escopos da aplicação. esta consiste de vários objetos cujos ciclos de vida dependem do escopo. Um exemplo comum é uma página. Este é um caso de um carrinho de compras. Desenvolvendo a página O Visual Web JSF possui diversos componentes que podem ser acessados através da janela Palette. Por padrão. cuja criação explicamos passo a passo a seguir. por exemplo.NET ou até mesmo com o próprio editor visual de aplicações Swing do NetBeans. dentro do pacote padrão. utilizando um escopo de requisição através da classe RequestBean1. Entretanto. Se você já trabalhou com ferramentas visuais como Delphi. haverá o preenchimento do carrinho até que seja esvaziado ou a página seja fechada.

Para finalizar. Selecione o Text Field “nascimento” e em Properties altere Converter>(New DateTimeConverter)2[2]. faça o “build” na classe SessionBean1. Pressionando <Shift>. selecione com um clique cada. que será arrastado para a página abaixo do formulário criado. utilizaremos o componente Table. 7. Adicione o componente Button na página e altere sua propriedade id para “btSalvar” e text para “Salvar”. ao lado de cada um dos rótulos inseridos. Altere a propriedade id na seqüência: “nome”. 8. Na caixa de diálogo (veja Figura 12).Figura 11. Na janela Navigator expanda Page1 e selecione dateTimeConverter1. 6. “telefone” e “nascimento”. 3. Arraste da janela Palette o componente Static Text para o Design da página. “Telefone:” e “Nascimento:”. Com o botão direito do mouse. “E-mail:”. Na janela Properties altere columns para 40. “email”. Arraste quatro componentes Text Field. conforme a Figura 11. Na janela Properties. Altere timezone para o seu fuso horário. Caso esta opção não esteja sendo exibida. um abaixo do outro e os alinhe. altere para contatos em Get Data From. Exibindo os contatos Para exibir os contatos. 2. Posicione-o e digite “Cadastro de Contatos”. 5. . os componentes: “nome” e “email”. digite em text os seguintes rótulos: “Nome:”. 4. ex. adicione o componente Message Group logo abaixo do formulário.: America/Sao_Paulo. Insira quatro componentes Label na página. selecione Table Layout no menu de contexto. Desenho da aplicação 1.

Confirme as mudanças clicando em OK. Definindo o layout da tabela Na caixa Selected surgirão os campos de Contato. selecione o texto estático da coluna “Nascimento” e altere a propriedade Converter>dateTimeConverter1. As colunas adicionadas serão links que executarão comandos. As demais existentes são componentes estáticos (Static Text). . conforme aponta a Figura 13. Selecione cada um e alterando sempre em Column Detail>Header Text o rótulo do cabeçalho que representa cada coluna na tabela.util.Date. Na guia Options altere Title para “Lista de Contatos”. utilizando os botões Up e Down. Perceba que este conversor é o mesmo utilizado para o campo Text Field “nascimento” do formulário.Figura 12. Na tabela. Este conversor tornará a representação da data pelo browser diferente da forma original encontrada no objeto java. Adicione duas novas colunas através do botão New. Altere Header Text e Value Expression do primeiro para “Editar” e do segundo para “Excluir”. Em Component Type mude para Hyperlink. Mude a ordem das colunas conforme a Figura 11.

Listagem 10. Ao fazer esta ação. que é o bean de Page1. alguns passos a mais serão necessários para trabalhar com os componentes que estamos utilizando neste exemplo.java. adicione o código da Listagem 10 para o link Editar do componente Table. Dê um duplo clique no link Editar da tabela de sua página. bastando somente selecionar o título da mesma. podemos ver em Properties>Events>action. email.Figura 13. No Design. nos resta adicionar a lógica para fazê-la funcionar. Adicionando código aos componentes Agora que temos a parte visual definida. na classe Page1. se colocar em JSP. telefone e nascimento. Automaticamente foi gerado um código. Retornando para Java. perceba que o Visual Web JSF o colocou em Java. em table1>tableRowGroup1 e selecione Add Binding Attribute no menu de contexto.getRowKey(). A propriedade width poderá ser usada caso queira maior precisão.1. Clique com o direito do mouse.jsp. Texto estático da coluna nascimento selecionado e alteração do converter Você poderá dimensionar a largura da coluna arrastando. } Ao mesmo tempo. verá que também foi adicionado o atributo actionExpression="#{Expressão}" em <webuijsf:hyperlink>. O mesmo deverá ser feito para os TextFields: nome. Isso significa que ao clicar no link Editar. automaticamente você invocará os eventos determinados no método hyperlink1_action(). No NetBeans 6. que representa o método que será invocado pelo link: public String hyperlink1_action(){ return null. //armazena o id do contato . na janela Navigator. Código do link Editar //link Editar do componente Table public String hyperlink1_action() { //pega a linha selecionada RowKey rowKey = getTableRowGroup1().

//retorna null por não haver navegação return null.parseInt(rowKey.getRowId())).getRowKey(). Listagem 11. } //retorna nulo por não mudar de página return null.setText(null).getContatoController().getSessionBean1(). Adicione o código da Listagem 11. //se houver algo em edição if (id != null) { Contato[] contatos = getSessionBean1(). Em seguida. telefone.setText(null). nascimento. faça o mesmo procedimento com o botão Salvar do formulário e altere como na Listagem 12.getId(). Integer id = Integer. Código do link Excluir //link Excluir do componente Table public String hyperlink2_action() { try { //captura a linha atual do link de exclusão clicado RowKey rowKey = getTableRowGroup1().getContatos(). //seleciona somente o contato que será editado Contato contato = contatos[id].excluir(contato). if (rowKey != null) { Contato[] contatos = getSessionBean1(). . //chama o controller para excluir o contato selecionado getSessionBean1().setText(null). } //limpa os campos existentes //caso esteja preenchidos nome. } catch (Exception ex) { //exibe o erro ao usuário info("Erro encontrado: " + ex).getRowId()).setId(Integer. //limpa o ID de SessionBean1 caso esteja com valor getSessionBean1(). //seleciona somente o contato que será removido Contato contato = contatos[id]. Código do botão Salvar //botão Salvar do formulário public String btSalvar_action() { Integer id = getSessionBean1().parseInt(rowKey.getContatos(). } Retorne para o Design e dê um duplo clique agora sobre o link Excluir da tabela. //informa ao usuário a exclusão info("Contato excluído!"). } Listagem 12. email.setId(null).setText(null).

setEmail(email.provider. } else { //caso seja um novo registro //cria um novo Contato Contato contato = new Contato(). } //limpa os campos existentes //caso esteja preenchidos nome. necessário para identificar qual contato será excluído ou editado.Date) nascimento. Nas Listagens 10 e 11 temos a manipulação do objeto com. } Para manipular um componente Table. //limpa o ID de SessionBean1 caso esteja com valor getSessionBean1().salvar(contato). email. usam RowKey para sua identificação. return null. o array contatos.toString()). onde obtemos o RowKey. Para a exclusão. através de getTableRowGroup1(). chamamos o método getRowKey().getText()). //atribui a este contato os valores definidos //nos campos do formulário da página contato. é utilizado para retornar somente . contato.setNascimento((java. contato. obtemos o valor de identificação da linha. um provedor de dados próprio.getText(). Para conseguir a linha selecionada. //informa que foi atualizado ao usuário info("Contato atualizado!").getContatoController().getText(). fornecida pela tabela.sun.setId(null). nascimento.toString()). //informa que foi salvo ao usuário info("Contato salvo!").getText()).getContatoController().toString()). telefone.setText(null).setNascimento((java.RowKey. contato.//altera seus valores em Contato contato. Muitos dos métodos para manipular a linha de dados.util.getText().toString()).setText(null).setTelefone(telefone.atualizar(contato). do objeto tableRowGroup1 (o nome do grupo do componente Table inserido na página).setEmail(email. encontrado em SessionBean1. o Visual Web JSF utiliza a classe TableDataProvider. que é um índice em uma linha de dados de um componente Table.setNome(nome. contato. contato.setText(null).getText(). que fornece acesso a um conjunto de informações organizadas por linhas-chaves. Com o método String getRowId().util.data.getText().getText(). //chama a atualização de ContatoController getSessionBean1(). contato.setText(null).setTelefone(telefone.Date) nascimento. Uma estratégia utilizada por TableDataProvider é armazenar a chave primária da fonte de dados dentro de um objeto RowKey.toString()).setNome(nome. //salva pelo método de ContatoController getSessionBean1().toString()).

Além do papel fundamental que o método prerender() tem para a edição dos dados. chamado pelo botão.getContatos(). No caso da edição. nascimento. Se houver. Já no botão Salvar. O método setText() fora utilizado para transmitir valores nulos com o intuito de limpar os campos após sua utilização.setText(contato.todosContatos(). exibido na Listagem 13. perceba que utilizamos o método getText(). com o código necessário para tal operação. Note que o link Editar da tabela possui apenas algumas linhas. simplesmente é criado um novo objeto Contato. fará uma verificação se há em sessão o id do contato que será atualizado. No caso de salvar. Para finalizar. Isso será feito chamando o método todosContatos() de SessionBean1. que retorna java. este também será responsável por sincronizar o componente Table com os dados encontrados no banco de dados. O componente Message Group é chamado.getEmail()). este valor é transmitido pela classe SessionBean1.setText(contato. } . através do método info(). Código do método prerender() public void prerender() { //capta o id armazenado em SessionBean1 Integer id = getSessionBean1(). que é transmitido ao método excluir() de ContatoController. } //atualiza todos os contatos //para o componente Table getSessionBean1(). para que o mesmo possa ser recuperado durante o ciclo de exibição dos dados no formulário e sua conseqüente submissão para alteração.getId().lang. Listagem 13. transmite os valores do formulário para Contato e chama o método atualizar() de ContatoController. sempre que houver uma operação sobre os mesmos. É exatamente este o papel do método “Callback” prerender().Object. que receberá os valores do formulário e seqüencialmente será transmitido para salvar() de ContatoController. preenchendo cada campo separadamente. O método btSalvar_action(). para informar ao usuário se a operação foi executada com sucesso. //preenche os campos do formulário nome. na edição dos dados. Para que o formulário funcione para edição. é porque está em edição if (id != null) { //capta os contatos Contato[] contatos = getSessionBean1(). transmitindo o id apenas do contato selecionado. para recuperar os dados encontrados em cada um dos componentes Text Field. através de Contato.setText(contato. temos duas tarefas a cumprir na submissão do formulário: atualizar ou adicionar dados. precisamos antes preencher o formulário. Para a manipulação dos campos do formulário. nas operações de salvar.getNome()).getTelefone()). através do atributo id. teremos que captar este valor antes da página ser renderizada e transmiti-lo.setText(contato.getNascimento()).um objeto Contato. //se não for nulo. email. //filtra somente o selecionado para edição Contato contato = contatos[id]. excluir e atualizar. telefone.

A Listagem 14 exibe o arquivo log4j. Preencha com log4j em File Name e confirme.org. compreender a estrutura do JavaServer Faces para trabalhar com o Visual Web JSF é importantíssimo.log4j.properties log4j. Assim. o Hibernate e a JPA.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L .hql=on log4j. suportado mais facilmente pelo NetBeans através de um plugin.log4j.Target=System. bibliotecas ou frameworks que sejam suportados “de fábrica” pelo Visual Web – mesmo o desenvolvimento visual pode ser habilitado para componentes de terceiros. Listagem 14.out log4j. com o direito sobre Source Packages selecione New>Other.layout=org. mesmo as que carecem de suporte direto.springframework = info Conclusões Neste artigo foi mostrado que o Visual Web JSF possui flexibilidade para trabalhar com outros frameworks.appender. com componentes arrastáveis no estilo WYSIWYG. Embora suas configurações sejam visuais.appender.logger. Em New File>Other>Properties File.ConsoleAppender log4j. através de um exemplo prático utilizando o Spring.appender.stdout.properties.Customizando a saída na janela Output A biblioteca de logging Log4j permite gerar uma saída organizada do que está acontecendo com a aplicação. os logs serão exibidos pela janela Output.layout.logger.stdout=org. .rootLogger=debug. Ao executarmos a aplicação dentro do NetBeans. mesmo tendo a grande maioria de seus componentes específicos à ferramenta. o que poupa muito trabalho do desenvolvedor.stdout. simplificou seu desenvolvimento com anotações. integrando suavemente com a JPA.appender.apache.PatternLayout log4j.org. Arquivo log4j. você não fica limitado a usar componentes.stdout. Para fazê-lo.logger.%m%n log4j. clique no botão Next. Vimos também que é simples integrar o Visual Web a outras tecnologias.apache. com pouca escrita em arquivo XML. Um fator importante no trabalho com Visual Web JSF é sua facilidade de desenhar aplicações JavaServer Faces.hibernate. stdout log4j. Aprendemos também que o Spring Framework.hibernate=debug log4j.org.

Sign up to vote on this title
UsefulNot useful