jun 22

Padrão Strategy aplicado com enum

Voltando a ativa, vou exemplificar algo simples e muito interessante de se utilizar, que é o padrão strategy. Uma maneira de identificar sua necessidade em um projeto é quando se tem um switch com muitos cases. Nesse caso você pode criar um enum da seguinte maneira:

 

     public enum MeuEnum {
          ITEM1 {
                public Object getLogicaItem() {
                      //código item 1
                 }
          },
           ITEM2 {
                public Object getLogicaItem() {
                      //código item 2
                 }
          };
          public abstract Object getLogicaItem();	
     }

 

E ao invés de utilizar um switch, basta agora atribuir o valor retornado do enum a variável desejada.

 

       Object item = ITEM1.getLogicaItem();

 

mai 03

Remoção de um item de datatable sem dar update no form inteiro no primefaces

Bom o título é grande mas o assunto é confuso. Contextualizando, imagine que você queira permitir ao seu usuário incluir vários campos de telefone, porém ele pode inserir N telefones, para isso você precisa que sejam campos dinâmicos.

No JSF  você pode fazer isso criando uma coleção no seu managedBean e utilizando o componente datatable. Assim ao inserir um novo telefone você chama um método que acrescenta um novo item a sua coleção e da update no datatable.

Porém digamos que o usuário adicionou acidentalmente um outro campo de telefone e queira removê-lo. Para isso é necessário um botão que faça tal ação, chamando um método do managedBean para remover o item desejado da lista.

Mas, porém, contudo, no entanto dentro de um datatable o update de um p:commandButton só funciona passando o parâmetro @form, que faz um refresh do formulário inteiro, o que nem sempre é desejado, pois somente queremos dar update no datatable.

Depois de muito discutir com amigos e pesquisar uma solução, descobri uma forma de fazer isso utilizando o componente p:remoteCommand, da seguinte maneira:

No botão de remover você faz:


<p:commandButton value="remover" type="button"
     onclick="removeRC({param:#{row}})" ></p:commandButton>

ATENÇÂO, a solução acima não se aplica para a versão 3.5+ do primefaces, caso esteja utilizando-a faça da seguinte maneira:


<p:commandButton value="remover" type="button"
     onclick="removeRC([{name:'param',value:#{row}}])" ></p:commandButton>

Onde row é o nome do atributo rowIndexVar do p:dataTable.

Aí fora da datatable vc usa um p:remoteCommand:


<p:remoteCommand name="removeRC" 
    update="datatableID" actionListener="#{MB.remove}">

</p:remoteCommand>

E pronto, é só agora fazer seu MB com os métodos como o exemplo abaixo e você conseguirá contornar esse bug do primefaces

@ManagedBean(name = "MB")
@ViewScoped
public class MB {

	private List<String> telefones;	

	public MB() {

		telefones = new ArrayList();
		for (int i = 0; i < 3; i++) {
			telefones.add(new String());
		}
	}		

	public void addList() {
		telefones.add(new String());
	}

	public void remove(ActionEvent event) {
		FacesContext context = FacesContext.getCurrentInstance();
		Map map = context.getExternalContext().getRequestParameterMap();		
		int row = Integer.parseInt(map.get("param"));
		telefones.remove(row);
	}

	public List getTelefones() {
		return telefones;
	}

	public void setTelefones(List telefones) {
		this.telefones = telefones;
	}
}

dez 14

Codigo Java dentro do javascript

Esse post vai ser bem curto, é só para mostrar que é possível chamar código java direto do html através de javascript, para fazer da seguinte maneira:

<script type="text/javascript">
           var data = new java.util.Date();
           alert(data);

</script>

Este código mostrará uma janela de alert com a data e hora do momento da execução, ele demonstra que para chamar alguma classe java deve-se declarar todo o caminho da classe. No caso de classes do pacote java é só chamar direto, no caso de classes personalizadas deve-se utilizar da seguinte maneira:

<script type="text/javascript">
           var minhaClasse = new Packages.meuPacote.minhaClasse();
           var retorno = minhaClasse.meuMetodo();
</script>

Para isso funcionar você precisa estar com essa classe no classpath da sua aplicação web. Mais informações basta olhar na documentação do Rhino

jul 25

Criando WebServices RESTful com Jersey, Maven e Tomcat no eclipse

Longo título, mas é isso que vou passar aqui nesse post. Se você procurar no google vai achar o passo-a-passo de introdução ao Jersey com maven. Porém em todos os tutoriais falta um detalhe que só consegui resolver depois de algumas muitas consultas ao google e tentativas frustradas.

Antes de tudo você deve instalar no seu eclipse o m2eclipse , é só copiar o update site e no seu eclipse ir em install new software e adicionar o update site.

Primeiramente a documentação do Jersey é muito boa, lá você tem tudo o que precisa para aprender a usá-lo. Portanto não vou falar detalhe a detalhe de como começar. Porém a introdução não mostra como integrar com Tomcat ( se você for na página de dependências ele mostra um link para como integrar com Servlets) .

Mas um tutorial bom e de fácil entendimento você encontra no MKYONG . Mas, porém contudo no entanto pule o passo 2, ao invés disso, crie um Dynamic Web Project no seu eclipse, e escolha como runtime environment o tomcat 6. Em seguida, clique com o botão direito no seu projeto e lá no finalzinho vai ter a opção Configure, escolha Convert to Maven Project . Após feito isso seu build path será todo desconfigurado. Você deverá então acessá-lo e reconfigurar a JRE, e apontar a pasta de códigos fontes na aba Source.

O build path agora está OK, porém ainda falta um passo, apontar para onde será feito o deploy dos fontes e das bibliotecas do maven.

Vá nas Propriedades do seu projeto e escolha Deployment Assembly, selecione add -> folder e escolha a pasta de códigos fonte , depois selecione add -> Java Build Path Entries e escolha Maven Dependencies . A pasta de códigos fontes deve ficar com o deploy path como WEB-INF/classes e a Maven Dependencies com o deploy path WEB-INF/lib como na figura abaixo.

 

Feito isso agora é só adicionar sua aplicação ao Tomcat e dar start.

jul 05

Upload de arquivos com primefaces

Quem usa JSF sabe que ele não tem tag nativa para upload de arquivos, para fazer funcionar , é preciso usar a tag html input e utilizar uma biblioteca da apache a commons-fileupload.

Porém algumas suites de componentes como richfaces , trinidad e tobago , e primefaces possuem essas tags. Nesse post vou focar no primefaces, pois considero a melhor dentre as apresentadas.

Antes é necessário que você baixe as seguintes bibliotecas e as adicione no classpath do seu projeto:

Em seguida você deve configurar seu web.xml caso você esteja usando Servlet 2.5, no caso do Servlet 3 eu não testei, mas acredito que não precise (quem usar, teste e comente por favor), adicionando o seguinte código abaixo:

        
	
        <filter>
                <filter-name>PrimeFaces FileUpload Filter</filter-name>
                <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
        </filter>
        <filter-mapping>
                <filter-name>PrimeFaces FileUpload Filter</filter-name>
                <servlet-name>Faces Servlet</servlet-name>
        </filter-mapping>

No sua página você deve usar a tag  p:fileUpload , ela possui vários atributos que podem ser setados, mas os principais são :

  • mode – que pode ser simple ou advanced, onde o simple ele renderiza um input file html comum; e o advanced (que é o default) ele renderiza apenas o botão de pesquisar e ao selecionar o arquivo ele já o valida, além de oferecer as opções de upload ou descartar.
  • allowTypes – lista-se as extensões que deverão ser aceitas
  • sizeLimit – tamanho máximo do arquivo
  • fileUploadListener – método do managed bean que quando for escolhido o mode advanced , trata o evento de upload( explicarei em seguida )
  • value – propriedade do tipo UploadedFile do managed bean que será feito o upload do arquivo, utiliza-se no caso do mode = simple

Exemplo:

    
<p:fileUpload fileUploadListener="#{mb.upload}"
     allowTypes="png,gif,jpg,jpeg" sizeLimit="10000"
     value="#{mb.arquivo}" mode="advanced"  />

Por fim deve-se no managed bean criar o método para o fileUploadListener :

     
private UploadedFile arquivo;
public void upload(FileUploadEvent event) {
    arquivo = event.getFile();
   /* implementação*//
}

E pronto. No labs do primefaces tem alguns exemplos de utilização, e usando você também descobre outras funcionalidades.

fev 14

Por que não usar richfaces

Em um outro post meu eu vim explicar como fazer funcionar richfaces 4 com jsf2, mas simplesmente não funciona. Na verdade eu estou exagerando, funcionar funciona, porém faltam muitos componentes que quem está acostumado a utilizar a versão 3.X do richfaces sente uma falta muito grande, quem usa primefaces então, esse chora de doer.
Tudo bem que ainda não é a release final do richfaces 4, mas sinceramente está muito capenga ainda. Componentes básicos como ordenar uma tabela, filtrar, sem contar os a4j:commandButton que são um parto para funcionar, eu mesmo desisti de os usar.
No final das contas migrei tudo para primefaces, agora com a versão 2.2 estável, não tem comparação, simplesmente é o melhor framework existente para jsf2.

jan 19

Utilizando Quartz para agendamento de tarefas

O Quartz é um serviço de agendamento de tarefas com diversas funcionalidades, como agendamento por período, com data marcada, etc.

Ele é livre para utilização e está sob a licença Apache 2.0. Agora neste post vou dar uma breve noção de como se agendar uma tarefa para ser executada em uma data específica.

Primeiramente criaremos a classe Tarefa.java que irá implementar a interface Job da biblioteca Quartz como no exemplo abaixo, e no método execute você desempenha a tarefa desejada.

public class Tarefa implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        System.out.println("Trabalhando");
        //Resto das atividades

    }

}

Para se chamar essa tarefa, em algum lugar da sua aplicação é necessário agendar sua execução da seguinte maneira:

SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();

JobDetail job = new JobDetail("Nome do Job que voce quiser",Tarefa.class);

java.util.Calendar cal = new java.util.GregorianCalendar(2011, Calendar.MARCH, 17);
  cal.set(cal.HOUR, 10);
  cal.set(cal.MINUTE, 30);
  cal.set(cal.SECOND, 0);
  cal.set(cal.MILLISECOND, 0);

Date dtInicio = cal.getTime();

SimpleTrigger disparo = new SimpleTrigger("Disparo da tarefa",dtInicio);
sched.scheduleJob(job, disparo);

Pronto, agora sua tarefa será executada no dia 17 de março de 2011 às 10:30, mas é óbvio que para isso sua aplicação precisará estar rodando até lá!

jan 18

Richfaces 4 com jsf 2 e tomcat 6

Lá vou eu me aventurar a utilizar o richfaces 4, que ainda está em versão de milestone 5. Mas vamo que vamo para ver o que ele tem de melhor ou pior que o primefaces.
Primeiro problema dele é a documentação falha, pois a última versão do richfaces vem com mais jars do que a documentação diz que precisa, e além disso são necessários outros 3 jars para conseguir rodar.

Assim é necessário baixar o richfaces e também os seguintes jars cssparser-0.9.5.jar, guava-r07.jar and sac1-3.jar e adicioná-los ao seu classpath para só então conseguir rodar sua aplicação jsf 2 com richfaces. A é claro que são necessárias também as bibliotecas do jsf 2 né.

Assim que tiver novidades postarei aqui, mas só para fazer rodar já me levou um tempinho, portanto fica aí a dica.

nov 10

JSF com JSTL, utilizando tag c:if

Primeiramente, não recomendo sua utilização, prefiro usar para testar se algum componente deve ser exibido ou não o atributo rendered das tags do JSF. Mas caso seja necessário sua utilização temos que atentar para 2 pontos, primeiro que a expressão não se inicia com # como as EL do JSF, mas sim com $;  segundo isso só funciona com jstl 1.1 ou 1.2, devendo ser utilizada assim a uri “http://java.sun.com/jsp/jstl/core” ao invés de “http://java.sun.com/jstl/core”, que é da 1.0 .

Assim sendo um teste simples ficaria da seguinte maneira:

<c:if test="${MB.atributo != null}">
      ...
</c:if>

É isso, estava passando por esse problema hoje e depois de googlar um pouco achei a solução e estou aqui repassando.

nov 08

Configurando JPA com Hibernate

Neste post vou mostrar o básico para fazer funcionar o JPA  com hibernate , utilizando o hsqldb, que é um banco de dados leve e muito bom para testes de desenvolvimento.

Inicialmente precisaremos das bibliotecas do hibernate que nesta versão já vem com as do JPA 2, porém isso não influenciará muito nessa configuração básica caso esteja usando o JPA. Agora crie uma pasta lib para colocar os .jar e adicione-os ao build path do projeto.

O segundo passo é criar a nossa Persistence Unit, que provê a definição do contexto de persistência, contendo os metadados relativos a tal.


Para isso deve ser criado um arquivo XML chamado persistence.xml e deve ser colocado dentro da pasta META-INF dentro da sua pasta de códigos fontes, no eclipse, utilizando a configuração default ficaria :  “src/META-INF/persistence.xml” . Este arquivo ficará com a seguinte configuração :

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.0">
    <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/nomedobanco" />
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />

            <property name="hibernate.connection.password" value="senha" />
            <property name="hibernate.connection.username" value="usuario" />

            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="show_sql" value="true" />
            <property name="format_sql" value="true" />

        </properties>
    </persistence-unit>
</persistence>

Obs.: Caso esteja utilizando o JPA  troque a linha da tag <persistence> por:

<persistence version=”1.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_1_0.xsd”>

Feito isso precisamos agora configurar como pegar o EntityManager, que é uma interface para interagir com o contexto de persistência.

Para isso criaremos um singleton que através da fábrica EntityManagerFactory pegaremos uma nova instância de EntityManager caso não tenha nenhuma aberta, ou retornará a que já está aberta. Será criada a classe JPAUtil:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
      private static EntityManagerFactory emf = null;
      private static EntityManager em = null;

      public static EntityManagerFactory getEntityManagerFactory() {
            if (emf == null)
                 emf = Persistence.createEntityManagerFactory("pu");
            return emf;
      }

       public static EntityManager getEntityManager() {
             if (em != null && em.isOpen())
                   return em;
             else {
                   em = getEntityManagerFactory().createEntityManager();
                   return em;
             }
       }

}

Isso já basta para testar se está funcionando, a conexão com o banco. Para testar agora criaremos uma classe de testes utilizando o JUnit para verificar se está tudo ok. Criaremos a classe JPATest:

import static org.junit.Assert.*;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import org.junit.Test;

public class JPAtest {
	@Test
	public void testaConexaoJPA() {
		EntityManager em = JPAUtil.getEntityManager();
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		transaction.commit();
		boolean isconectado = em.isOpen();
		em.close();
		assertTrue(isconectado);
	}
}

Pronto, se tudo estiver correto ficará verde o teste do JUnit. Em outro post mostrarei como implementar um DAO para JPA.