Início > programação, programação JSF > Usando RestFaces na sua aplicação JSF – trabalhando com requisições GET

Usando RestFaces na sua aplicação JSF – trabalhando com requisições GET

Hoje me deparei com um problema aqui no trabalho: uma aplicação nossa em PHP iria chamar uma aplicação JSF passando parâmetros GET que deveriam ser tratados e, dependendo dos dados recebidos, essa aplicação JSF redirecionaria o usuário para uma view ou para outra. Além disso, o sistema em JSF deveria armazenar algumas das informações vindas pela URL para posteriormente exibir na tela para o usuário.

Já sabia que para trabalhar com bookmarking no JSF era necessário utilizar algum componente externo e o mais famoso é o RestFaces. A primeira iniciativa foi então pesquisar como eu iria realizar os seguintes passos:

  1. Tratar esses parâmetros vindos do sistema PHP;
  2. Armazenar os dados recebidos em propriedades dos beans;
  3. Direcionar o usuário para uma das duas telas predefinidas.

O RestFaces tem várias funcionalidades bastante úteis e permite invocar métodos server-side através de uma simples requisição GET HTTP. Ele lhe ajuda bastante no gerenciamento de parâmetros da seguinte forma:

  • Permite passar parâmetros da URL para os métodos server-side;
  • Converte parâmetros;
  • Renderiza parâmetros;
  • Alinha propriedades dos Beans aos parâmetros da URL e vice-versa.

A solução que encontrei para meu problema (poderia ser feito de outras formas) foi apenas criar duas RestFaces Actions.

Vamos ao passo-a-passo:

  1. Primeiro vamos instalar o RestFaces na nossa aplicação
    1. Baixe a última distribuição do RestFaces em https://restfaces.dev.java.net;
    2. Ponha o jar do RestFaces no seu classpath;
    3. Ponha as seguintes informações no seu faces-config.xml
    4. <faces-config>
         <application>
            <view-handler>org.restfaces.application.RestViewHandler</view-handler>
            <navigation-handler>org.restfaces.application.RestNavigationHandler</navigation-handler>
            ...
         </application>
         ...
      </faces-config>
      
    5. Adicione a seguinte linha à JSP da sua aplicação:
    6. <%@ taglib uri="http://restfaces.dev.java.net" prefix="rest" %>
      

      Caso esteja usando facelets, declare da seguinte forma:

      xmlns:rest="http://restfaces.dev.java.net"
      
  2. Pronto, o RestFaces está instalado.

  3. Vamos agora declarar a primeira RestFacesAction
    1. Para isso, deveremos colocar as anotações que vão configurar nosso método como uma RestFaces Action e permitirão receber os parâmetros da URL (maiores detalhes sobre as anotações e as propriedades de uma RestFaces Action no fim do post). No meu sistema essa action deverá ser chamada quando eu quero detalhar um curso. Vamos ao exemplo:
    2. public class CursoBean {
         private Curso curso;
         private String cidade;
         private int qtdAlunos;
         private List<Aluno> alunos;
      
         @Instance("#{cursoBean}")
         @HttpAction(value="cursoAction", pattern="curso")
         public String getCursoById(@Param("idCurso") long idCurso, @Param("cidade") String cidade, @Param("qtdAlunos") int qtdAlunos) {
            curso = new CursoService().getCursoById(idCurso);
            this.cidade = cidade;
            this.qtdAlunos = qtdAlunos;
      
            return "detalhaCurso"; //navigation-rule do JSF
         }
      
         //getters e setters ...
      
      }
      
  4. Agora vamos chamar nossa action através de um rest:link
  5. <rest:link value="cursoAction">
       <f:param name="idCurso" value="#{curso.id}"/>
       <f:param name="cidade" value="#{curso.cidade.nome}"/>
       <f:param name="qtdAlunos" value="#{curso.qtdAlunos}"/>
       <h:outputText value="#{curso.nome}"/>
    </rest:link>
    
  6. Nossa URL final ficará http://www.meusite.com.br/curso.jsf?idCurso=123&cidade=Fortaleza&qtdAlunos=35. Quando for feita uma requisição com esse caminho, o RestFaces reconhecerá como uma Action dele – por conta do pattern curso.jsf – e chamará o método do Bean;
  7. Esse exemplo é apenas trivial (na maioria dos casos não tem sentido passar a cidade e a quantidade de alunos de um curso através de parâmetro).
    Lembrando que no meu cenário, não posso ter um rest:link, já que a aplicação que faz a requisição é PHP. A solução foi fazer com que a URL chamada pelo outro sistema fosse exatamente a que está acima.

  8. Agora vamos declarar a outra action que deve ser chamada quando quero mostrar a lista de alunos de um curso. Como o bean é o mesmo, vou mostrar apenas o outro método:
  9.    @HttpAction(value="alunosCursoAction", pattern="alunosCurso")
       public String getAlunosDoCurso(@Param("idCurso") long idCurso) {
          curso = new CursoService().getCursoById(idCurso);
          alunos = new AlunoService().getAlunosDoCurso(idCurso);
    
          return "listaAlunosDoCurso"; //navigation-rule do JSF
       }
    }
    
  10. Agora vamos chamar nossa action através de outro rest:link
  11. <rest:link value="alunosCursoAction">
       <f:param name="idCurso" value="#{curso.id}"/>
       <h:outputText value="Alunos de #{curso.nome}"/>
    </rest:link>
    
  12. Nossa URL final ficará http://www.meusite.com.br/alunosCurso.jsf?idCurso=123.Mais uma vez, não posso ter um rest:link, já que a aplicação que faz a requisição é PHP, portanto vou chamar pelo outro sistema a URL que está acima.
  13. Muitos desenvolvedores, entretanto, não gostam dessa forma tradicional de passagem de parâmetros. Eles preferem path parameters como /biblioteca.jsf/livro/1365. No teste anterior, a nossa URL ficaria assim:  http://www.meusite.com.br/alunosCurso.jsf/123. Para que isso funcione, precisamos primeiro adicionar o filtro do RestFaces no web.xml, conforme abaixo:

    <filter>
      <filter-name>RestFaces Filter</filter-name>
      <filter-class>org.restfaces.Filter</filter-class>
      <init-param>
        <param-name>faces-mapping</param-name>
        <param-value>*.jsf</param-value>
      </init-param>
    </filter>
    
    <filter-mapping>
      <filter-name>RestFaces Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    Agora vamos mudar o pattern da nossa Action. O nosso método ficaria assim:

       @HttpAction(value="alunosCursoAction", pattern="alunosCurso/{idCurso}")
       public String getAlunosDoCurso(@Param("idCurso") long idCurso) {
          curso = new CursoService().getCursoById(idCurso);
          alunos = new AlunoService().getAlunosDoCurso(idCurso);
    
          return "listaAlunosDoCurso"; //navigation-rule do JSF
       }
    }
    

    Os elementos {var} do pattern são automaticamente preenchidos com os parâmetros anotados.


Por dentro de uma RestFaces Action:

  • cursoAction (obrigatório): nome único da Action no RestFaces. Usado para a view referenciar a action;
  • cursoBean: pode ser um Managed-Bean JSF ou um bean simples que possa ser acessado via expression language (EL) com #{cursoBean};
  • pattern (opcional, porque é reconhecido pelo nome da action): é a principal parte gerada na URL: no nosso caso ficou /curso.jsf?idCurso=123&cidade=Fortaleza&qtdAlunos=35;
  • @Param: associa o parâmetro HTTP ao parâmetro do método. Realiza também qualquer conversão necessária (exemplo: de String para int);
  • @Instance especifica em que instância deve ser executado esse action. Ao invés de usar a mesma anotação em cada método, basta uma anotação por classe.
Anúncios
  1. 17/12/2009 às 10:31

    nice job!

  2. Hélio Moura
    17/12/2009 às 16:22

    Caro Pablo, Acho que a idéia de integração do JSF com REST é muito interessante pois é muito fácil desenvolver serviços em REST. Além disto existe um tendência forte de se usar Facelets no lugar de JSP. Portanto uma ótima combinação seria JSF-Facelets-REST. Ainda não conheço o RestFaces, agora vou estudá-lo!
    Parabéns pelo seu trabalho.

  3. Ricardo
    19/05/2010 às 02:02

    Olá Muito bom o teu post. Me ajudou muito esta api.
    Porem faltou uma configuracao no web.xml.

    org.restfaces.DEVELOPMENT
    true

    RestFaces Filter
    org.restfaces.Filter

    faces-mapping
    .jsf

    RestFaces Filter
    /*

    • 19/05/2010 às 10:13

      É verdade Ricardo. Esqueci desse detalhe. Já corrigi a informação no post. Abraço.

  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s

%d blogueiros gostam disto: