O uso do Ajax é, atualmente, uma necessidade comum em projetos web, independentemente da linguagem de programação e frameworks utilizados em sua construção. No ambiente Java, o JSF facilita a implementação desse recurso através de componentes que nos ajudam a realizar chamadas assíncronas sem lidar diretamente com o JavaScript. Essa facilidade, porém, também traz um problema: a falta de controle do desenvolvedor sobre o ciclo de vida do Ajax, pois tudo é feito de forma automática pelo JSF.

Nesse artigo, veremos como interceptar as requisições assíncronas e realizar ações específicas em seu contexto, como mostrar uma mensagem de “carregando” quando elas forem iniciadas, demonstrando para o usuário que algum processo está sendo realizado.

Passo 1: Preparação do ambiente

Para que seja possível interceptar as chamadas assíncronas em uma página do JSF, é necessário importar o arquivo jsf.js, que se encontra na biblioteca javax.faces e que contém as funcionalidades para lidar com Ajax. Isso pode ser feito por meio do componente outputScript, da seguinte forma:

<h:outputScript library="javax.faces" name="jsf.js" target="head" />

Geralmente, adicionamos essa linha ao final da página, antes do fechamento da tag <body>, para melhorar a performance, pois assim o JavaScript é carregado apenas após todos os componentes da interface gráfica estarem prontos. Se a biblioteca tiver sido carregada corretamente, após a renderização da página você verá o seguinte código:

<script type="text/javascript" src="/seuprojeto/javax.faces.resource/jsf.js?ln=javax.faces&stage=Development"></script>

Passo 2: Interceptação de requisições Ajax

Para que possamos utilizar os objetos e funções contidos no arquivo jsf.js, precisaremos referenciá-los a partir de um código JavaScript em nossas páginas. Aqui, optaremos por criar um outro arquivo, chamado main.js, no qual vamos escrever o código necessário para lidar com as requisições, mantendo o JavaScript separado do HTML. O conteúdo desse arquivo pode ser visto na Listagem 1.

Listagem 1. Estrutura inicial do arquivo main.js

  $(document).ready(function() {
      jsf.ajax.addOnEvent(handleAjaxEvents);
  });
  function handleAjaxEvents(data) {
  }

Note, nesse código, que também estamos utilizando a biblioteca jQuery, para simplificar a escrita do código JavaScript; no entanto, isso não é obrigatório. É importante garantir, contudo, a chamada ao jsf.ajax.addOnEvent após o carregamento da página, como fizemos nas linhas 1 a 3.

Perceba que o argumento do método addonevent é a função que será responsável por tratar as requisições Ajax. Assim, toda vez que uma requisição desse tipo for disparada, o método handleAjaxEvents, definido nas linhas 4 e 5, será chamado, recebendo o argumento data com os dados necessários para monitoramento do processo, como seu status.

Após salvar o arquivo main.js, é necessário importá-lo na página JSF. Para isso, podemos utilizar as seguintes instruções, que referenciam a biblioteca jQuery, o arquivo jsf.js e o main.js:


   <h:outputScript name="plugins/jQuery/jQuery-2.1.4.min.js" />
   <h:outputScript library="javax.faces" name="jsf.js" target="head" />
   <h:outputScript name="main.js" />

Feito isso, podemos evoluir a função handleAjaxEvents, adicionando a ela a lógica para lidar com as diferentes etapas de cada requisição assíncrona. Na Listagem 2, por exemplo, temos o código para exibir uma mensagem quando a requisição for finalizada com sucesso.

Listagem 2. Verificando se a requisição foi bem sucedida
function handleAjaxEvents(data) {
         if (data.status === "success") {
               alert("Requisição AJAX completada sem erros.");
         }
  }

O valor do atributo data.status varia de acordo com a etapa em que se encontra a chamada assíncrona e, além do valor “success” utilizado nesse exemplo, também podemos, por exemplo, identificar quando a requisição foi iniciada e concluída, independentemente de ter havido erro ou não. Na Listagem 3 é apresentado o código desse exemplo.

Listagem 3. Outros status da requisição AJAX

  function handleAjaxEvents(data) {
      if (data.status === "begin") {
            mostrarCarregando();
      } else if (data.status === "success") {
            console.log("Requisição AJAX efetuada sem erros");
      } else if (data.status === "complete") {
            esconderCarregando();    
      }
  }

Nas linhas 2 e 3, identificamos que a requisição foi iniciada e, portanto, devemos exibir uma mensagem do tipo “Carregando” para o usuário. Já nas linhas 6 e 7, ocultamos essa mensagem quando a requisição é finalizada. Aqui é importante destacar que o status “complete” pode ser atingido mesmo que ocorra erro na chamada. Nesse caso, não passaríamos pelo status “success”.

A partir dessa estrutura, podemos realizar diversos procedimentos em cada etapa da requisição. Com essa técnica é possível, por exemplo: bloquear os campos da tela até que uma resposta seja obtida do servidor ou notificar o usuário de eventos a partir de janelas modais, muito utilizadas em aplicações web.