terça-feira, abril 24, 2007

Que suador! Primeiro contato com JSF My Faces

Dae galera, tudo tranqüilo?
Semana passada comprei o livro do Budi Kurniawan Programando em JavaServer Faces para aprender sobre o framework (que fora adotado pela empresa que eu trabalho em substituição ao WebWork).

Montando o ambiente de desenvolvimento na minha máquina em casa (dor de cabeça número 1):

- JDK 6 + Tomcar 6 + JSF implementado pela Sun

Nada funcionava! Não conseguia acessar a aplicação sem ter uma porrada de erros dos mais bizarros. Baixava os exemplos do livro, e outros, e nada de funcionar... cheguei a me desiludir um pouco, mas bola para frente a vida de “javeiro” não é mole não!

Baixei a implementação My Faces da Apache, troquei a porcaria do Tomcat 6 por uma versão 5.5 porque o Merve não reconhecia o Tomcat 6 como um Tomcar válido, e, bingo... consegui acessar a minha aplicação com dois links bem simples redirecionando o navegador através das regras de navegação e tudo mais.

Quase tudo perfeito, aí descobri que a maioria dos exemplos do livro (escrito em 2004) e de um outro que eu tenho aqui (Pro JSF and Ajax) não funcionavam porque eram baseados em implementações mais antigas do JSF! :(

Caraca, daí começa a briga da semana com as tags que formam a página, os métodos nos beans do exemplo e tudo mais...


Depois de muito peleiar por “essa internet sem fim” consegui resolver os problemas da minha página JSP :) e parti para o bean e a classe do meu exemplo (quem não conhece o livro é uma página com dois campos que se insere números e abaixo se tem um botão que os somam).

Bom somar os números, atribuir os campos da tela a um bean foi relativamente rápido. Ele (JSF) faz tudo para ti, só dizer que o campo é referente a um campo do bean e era isso! Até o funcionamento da página é fácil se você tem campos getters para todos os campos...

Mas porém, ah porém, sempre que eu entrava na página aparecia uma mensagem de erro dizendo:

Unable to find component 'firstNumber' (calling findComponent on component 'form:_idJsp1'). We'll try to return a guessed client-id anyways - this will be a problem if you put the referenced component into a different naming-container. If this is the case, you can always use the full client-id.

Bom o que ele queria me dizer, já ao carregar a minha página, era que a tag de label vinha após a tag que representava meu input. Bom dicas que encontrei na intenet:

a) colocar label APÓS input! Isso para quem já desenvolveu interfaces em xhtml soa estranho de mais!
b) colocar minhas tags de label e input dentro de uma outra tag, como panelGroup. Bem, foi o que eu fiz e começou a me dar erro dizendo que todo e qualquer conteúdo html eu deveria encapsular entre <f:verbatim></f:verbatim>... ahhh, mais trabalho po! Mas foi que eu fiz para não ter que optar pela opção a :P .

Depois deste trauma superado e da minha página funcionando com uma JSP e um bean parti para a segunda parte do exemplo que era usar ActionListener com ActionEvent. A moral da história era pegar o componente que disparou o evento, o elemento root da página e imprimir a estrutura que representava a árvore de componentes da página.

Dae começaram meus problemas novamente... mas depois de muito “googliar” e encher o saco do pessoal da lista de discussões do RSJUG, resolvi... e eram ridículos os erros:


a) meu commandButton estava chamando uma action e não actionListener como deveria;
b) depois eu não sabia como suprir a falta de alguns métodos que não existiam mais na implementação;
c) mais uma barberagem com um while (nossa que vergonha, mas era tarde, tava cançado ...:P );

Enfim... tomei um sarrafo!!! Uma surra. Mas está rolando!!! Uhú!
Agora pelo menos eu consegui fazer o primeiro exemplo do livro (putz) mas com direito a validações e tal... (muito fácil de fazer também).


Em resumo, meu exemplo da classe listener implementada em My Faces 1.1.5 para o exemplo do livro:

package estudo.jsf;

import java.util.Iterator;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;

public class SomarAction {

    public PhaseId getPhaseId() {
        return PhaseId.APPLY_REQUEST_VALUES;
    }

    public void montarArvore(UIComponent componente, int nivel) {

        for(int i = 0; i < nivel; i++) {
            System.out.print(" ");
        }

        System.out.println(componente.getId());

        Iterator children = componente.getChildren().iterator();

        while(children.hasNext()) {
            UIComponent child = (UIComponent) children.next();
            montarArvore(child, nivel + 1);
        }
    }

    public void processAction(ActionEvent event) {
        System.out.println("..... processando a acao\n");

        //--- descobre quem invocou essa ação
        UIComponent componente = event.getComponent ();
        System.out.println("..... objeto disparador da acao: " + componente.getId() + "\n");
        //---- fim

        //--- descobre quem é o elemento root
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIComponent componenteRaiz = facesContext.getViewRoot();
        System.out.println("..... objeto root: " + componenteRaiz.getId() + "\n");
        //---- fim

        //--- imprime a estrutura da árvore de componentes da tela
        System.out.println("-------------- arvore de componentes --------------");
        montarArvore(componenteRaiz, 0);
        System.out.println("---------------------
------------------------------");

        //--- fim
    }
}

Bom acabei de resolver os problemas e tal e to cançadão... juro que mais para frente tento explicar o exemplo. Quem quizer o código posta um comentário aí com seu e-mail que eu mando.

T+

3 comentários:

Bruno B disse...

por essas e outras que nao gosto de JSF... :D

olha no meu blog o post sobre Wicket!

[]'s!
miojo

Anônimo disse...

ola, to fazendu um trabalho sobre JSF com tomcat, gostaria de saber se vc tem alguem codigo que pudesse me passar.
Obrigado
Samuel_uai@hotmail.com

Alexandre Ferreira disse...

Fala amigo, muito engracado o post.
Bom humor, nada melhor que rir nas 16:50 da tarde =)

Amigo, eu estava procurando referencias sobre os livros (Pro jsf e Core Jsf) O Core vc conhece?

Agora vc citou um que nao conhecia e o pro Jsf , vi que ambos estao bastante desatualizados...

Que pena, abracao!

Estou saindo dos frameworks Actions também.

Envia-me o codigo por favor: alexandreee@gmail.com