Executando ações pela URL no JSF

O PrettyFaces possui um mecanismos que facilita a chamada de métodos através da URL no JSF,pois já possui um filtro implementado escutando a configuração feita no pretty-config.xml.
No exemplo a baixo será uma simulação de uma loja virtual, que ao clicar no produto abre a página do produto com a URL formatada em : produto/Categoria/ID/Descrição e o parâmetro de ação será o ID do produto ou seja qualquer alteração nos outros parâmetro não será chamado o Controller/ManagedBean.

Dependências

pom.xml

<dependency>
    <groupid>org.ocpsoft.rewrite</groupid>
    <artifactid>rewrite-servlet</artifactid>
    <version>2.0.4.Final</version>
</dependency>
<dependency>
    <groupid>org.ocpsoft.rewrite</groupid>
    <artifactid>rewrite-config-prettyfaces</artifactid>
    <version>2.0.4.Final</version>
</dependency>
<dependency>
    <groupid>org.ocpsoft.rewrite</groupid>
    <artifactid>rewrite-integration-cdi</artifactid>
    <version>2.0.4.Final</version>
</dependency>

Configuração

Criar o arquivo pretty-config.xml dentro de webapp/WEB-INF.

Observação
O filtro do prettyFaces apenas serão executados nos xhtml que estiverem referenciados dentro do pretty-config, caso não esteja dentro do arquivo terão o comportamento normal de xhtml dentro do JSF.

pretty-config.xml

<pretty-config xmlns="http://ocpsoft.org/schema/rewrite-config-prettyfaces" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://ocpsoft.org/schema/rewrite-config-prettyfaces http://ocpsoft.org/xml/ns/prettyfaces/rewrite-config-prettyfaces.xsd">

    <url-mapping id="viewListaProduto">
        <pattern value="/pages/listaProdutos" />
        <view-id value="/pages/listaProdutos.xhtml" />
    </url-mapping> 

    <url-mapping id="viewProduto">
        <pattern value="/pages/produto/#{categoria}/#{idProduto : produtoController.idUrlParametro}/#{descricao}" />
        <view-id value="/pages/produto.xhtml" />
        <action>#{produtoController.abrirProduto}</action>
    </url-mapping>                    
                      
</pretty-config>
  • pattern : URL a ser apresentanda
  • view-id : Arquivo xhtml que deverá ser escutado pelo filtro.
  • action : Método do controller/ManagedBean a ser chamado ao renderizar página.

Existem 2 formas de passar parâmetros no pattern :

  • Parâmetro da request: É apenas adicionado uma variável após o separador “/”, que esperará o valor de parâmetro vindo da request, ex : #{categoria}
  • Referenciar um atributo do Controller/ManagedBean: A variável da URL receberá o valor que estiver no campo referenciado do Controller/ManagedBean, ex : #{idProduto : produtoController.idUrlParametro}
Observação

  • No atributo pattern podem sem adicionado quantos parâmetros forem preciso separados por “/”;
  • A quantidade de parâmetros esperados no patterns deve ser a mesma quantidade passada na chamada da página, caso não for será lançada uma a exception e a tela não será renderizada;

Implementação

Criar um Controller/ManagedBean para gerenciar criar uma lista de produtos, armazenar o id do produto selecionado para enviar por parametro e consultar id vindo por parametro.

ProdutoController.java

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.validator.ValidatorException;

import org.business.teste.product.Product;
import org.business.teste.service.product.IProductService;

@ManagedBean(name = "produtoController")
@SessionScoped
public class ProdutoController implements Serializable {

 private static final long serialVersionUID = 1L;

 private List<Produto> produtos;

 private Produto produtoSelecionado;
 private String idProdutoUrl;

 @EJB
 private IProductService productService;

 @PostConstruct
 public void listarTodosProdutos() {
  this.produtos = this.productService.findAll();
 }

 public void abrirProduto() {
  try {
    this.produtoSelecionado = this.productService.findById(Long.valueOf(this.idProdutoUrl));
  } catch(NumberFormatException ne) {
    throw new ValidatorException(new FacesMessage("Parametro Inválido"));
  }
 }
  • Criar uma lista de produtos e carrega – lá para utilizar na listagem de produtos;
  • Criar um atributo idProdutoUrl para armazenar o valor do id do produto a ser pesquisado;
  • Criar um método que consulte o produto pelo id vindo do parâmetro idProdutoUrl;

Criar uma página para a listagem de todos os produtos.
produtos.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pretty="http://ocpsoft.com/prettyfaces">

    <body>
        <h:form>
            <h2>Lista de Produtos</h2>

            <p:dataTable value="#{produtoController.produtos}"
                 var="product"  rows="5"  style="width: 40%"
                 paginatorTemplate="{CurrentPageReport}  {FirstPageLink}
                                    {PreviousPageLink} {PageLinks}
                                    {NextPageLink} {LastPageLink}
                                    {RowsPerPageDropdown}"
                                    rowsPerPageTemplate="5,10,15">

                 <p:column headerText="ID" sortBy="#{produto.id}" >
                     <h:outputText value="#{produto.id}" />
                 </p:column>
                 <p:column headerText="Categoria" sortBy="#{produto.categoria}">
                     <h:outputText value="#{produto.categoria}" />
                 </p:column>
                 <p:column headerText="Decrição" sortBy="#{produto.descricao}">
                     <h:outputText value="#{produto.descricao}" />
                 </p:column>
                 <p:column headerText="Opções" >
                     <pretty:link mappingId="viewProduto" title="Open">
                         <h:outputLabel value="Open " />
                         <f:param value="#{produto.categoria}" />
                         <f:param value="#{produto.id}" />
                         <f:param value="#{produto.descricao}" />
                     </pretty:link>
                  </p:column>
              </p:dataTable>
        </h:form>
    </body>
</html>

Feito a lista de produtos é preciso um link para seleção do produto selecionado para enviar os parâmetros necessários para construir a URL e realizar a consulta para carregar o produtoSelecionado.

  • pretty:link : Componente do prettyFaces que tem um comportamento similar do h:link ou seja é processado no lado do cliente;
  • mappingId : É o atributo que define qual configuração do pretty-config.xml utilizar quando clicar no link;
  • f:param : É os valores dos parâmetro esperado na configuração do viewProduto no pretty-config.xml, ou seja, foram configurado 3 parâmetros então é necessário enviar 3 parâmetros;
Observação
Utilizando o componente pretty:link facilita o envio de parâmetros, usando a tag f:param para definir os parâmetros e apenas se preocupando com o tipo(apenas tipos primitivos) e a ordem deles.

Criar uma página para abrir o produto.
produto.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pretty="http://ocpsoft.com/prettyfaces">

    <body>
        <h1>Produto</h1>

        <h:form>

        <h:panelGrid columns="2">
            <h:outputLabel value="ID: " />
            <h:outputLabel value="#{produtoController.produtoSelecionado.id}" />

            <h:outputLabel value="Categoria: " />
            <h:outputLabel value="#{produtoController.produtoSelecionado.categoria}" />

            <h:outputLabel value="Descrição: " />
            <h:outputLabel value="#{produtoController.produtoSelecionado.descricao}" />
        </h:panelGrid>

        <br />

        <pretty:link mappingId="viewListaProduto">
            <h:outputLabel value="Voltar" />
        </pretty:link> 

        </h:form>
    </body> 
</html>

Ao clicar no link do produto na página produtos.xml, segundo a configuração do pretty-config, será chamada a action : produtoController.abrir() que pegará o valor do idProdutoUrl e fará uma consulta no banco de dados para carregar o produtoSeleciado em seguida, seguindo a configuração, será redirecionado para página de produto.xhtml.

Observação
O único parâmetro que afeita na ação é o segundo (id), então qualquer alteração nos outros parâmetros não será executado nada.

Resultado : http://localhost:8080/projeto/produto/CALCA/1/CALCA-JEANS

Anúncios

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