Pretty URL com JSF 2 e Demoiselle 2

04jul11

Quem aí sabe o que é pretty url, também conhecido como simple url? Há quem chame de url rewrite. Tanto faz! O que importa mesmo é para que serve. Se você não sabe, não deixe de ler este post completo. Se você sabe do que se trata, vou mostrar como implementar na sua aplicação web com JSF 2 e Demoiselle 2.

Recentemente precisei utilizar pretty urls (indicado por Paulo Suzart) em um projeto com JSF 2 e Demoiselle 2. Então comecei mais uma longa jornada de experimentar diversas soluções do mercado. Achei uma muito prática e simples de usar. Ops… vamos com calma! Que diacho é pretty url?

Ao acessar o Twitter você está usando pretty urls, olha só: http://twitter.com/zyc. Ao escrever “/zyc”, você vai diretamente para a página do usuário “zyc”. Olha outro exemplo: http://americanas.com.br/produto/7107451. Agora que você sabe o que é, vai perceber que é muito comum na Internet. Quer fazer isto na sua aplicação?!

No exemplo utilizei o framework Demoiselle 2 para facilitar minha vida, mas funcionaria em qualquer aplicação com JSF puro também. Criei a aplicação com base no post Iniciando com o Demoiselle 2.0. Com o Maven gerei o projeto a partir do arquétipo demoiselle-jsf-jpa (versão 2.1.0).

Utilizando o arquétipo demoiselle-jsf-jpa

Ao final do processo, minha aplicação estava pronta. O Demoiselle criou o projeto contendo um caso de uso modelo: o bookmark. Trata-se de uma listagem básica e edição dos registros. Ao acessar a página de listagem, a url no navegador finaliza assim: /bookmark_list.jsf. Mas eu gostaria que fosse simplesmente assim: /bookmark. A tela de edição está assim: /bookmark_edit.jsf?id=1. Quero que fique assim: /bookmark/1.

É óbvio que não implementei na mão! Pesquisei e achei várias soluções. As que mais gostei foram: Url Rewrite Filter e PrettyFaces. Optei pela PrettyFaces por quatro motivos: (1) a documentação está muito bem elaborada; (2) o código-fonte está hospedado no GitHub, o que facilita a evolução do projeto; (3) está mais bem integrado com o Maven e; (4) funciona redondamente com JSF.

Abri o arquivo pom.xml do meu projeto e inclui a seguinte dependência:

<dependency>
	<groupId>com.ocpsoft</groupId>
	<artifactId>prettyfaces-jsf2</artifactId>
	<version>3.3.0</version>
</dependency>

No web.xml declarei o filtro (opcional para JSF 2):

<filter>
	<filter-name>Pretty Filter</filter-name>
	<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>Pretty Filter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>FORWARD</dispatcher>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

Criei o arquivo pretty-config.xml na pasta WEB-INF com o seguinte conteúdo:

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

	<rewrite match="^/(.*)/$" substitute="/$1" redirect="301" />

	<url-mapping id="index">
		<pattern value="/" />
		<view-id value="/index.jsf" />
	</url-mapping>

	<url-mapping id="bookmark-list">
		<pattern value="/bookmark" />
		<view-id value="/bookmark_list.jsf" />
	</url-mapping>

	<url-mapping id="bookmark-new">
		<pattern value="/bookmark/new" />
		<view-id value="/bookmark_edit.jsf" />
	</url-mapping>

	<url-mapping id="bookmark-edit">
		<pattern value="/bookmark/#{id}" />
		<view-id value="/bookmark_edit.jsf" />
	</url-mapping>
</pretty-config>

Utilizei a tag <rewrite> para remover as barras no final da url, caso exista. O primeiro mapeamento define que ao acessar a raiz, a página index.jsf atenderá a requisição. O segundo define a tela de listagem. O terceiro a edição.

Removi o arquivo index.html do projeto e fiz as seguintes modificações no bookmark_list.xhtml:

<!--
<p:commandButton title="#{messages['button.new']}" image="ui-icon-document" action="#{bookmarkListMB.getNextView}"
	actionListener="#{bookmarkListMB.clear}" ajax="false" />
-->

<p:commandButton title="#{messages['button.new']}" image="ui-icon-document" action="pretty:bookmark-new"
	actionListener="#{bookmarkListMB.clear}" ajax="false" />

Ainda no bookmark_list.xhtml, substituí a tag <h:commandLink> por <h:link> para possibilitar a passagem do parâmetro id através de query string:

<!--
<h:commandLink action="#{bookmarkListMB.getNextView}" actionListener="#{bookmarkListMB.clear}">
	<h:outputText value="#{bean.description}" />
	<f:param name="id" value="#{bean.id}" />
</h:commandLink>
-->

<h:link outcome="#{bookmarkListMB.nextView}" value="#{bean.description}">
	<f:param name="id" value="#{bean.id}" />
</h:link>

Modifiquei as anotações da classe BookmarkListMB para retornar o padrão bonito:

@ViewController
//@NextView("/bookmark_edit.xhtml")
//@PreviousView("/bookmark_list.xhtml")
@NextView("pretty:bookmark-edit")
@PreviousView("pretty:bookmark-list")
public class BookmarkListMB extends AbstractListPageBean {
	...
}

E o mesmo para o controlador BookmarkEditMB da tela de edição:

@ViewController
//@PreviousView("/bookmark_list.xhtml")
@PreviousView("pretty:bookmark-list")
public class BookmarkEditMB extends AbstractEditPageBean {
	...
}

Por fim, fiz deploy no JBoss AS 6. A tela de listagem ficou assim:

Listagem de bookmark

A edição assim:

Edição de bookmark

E inclusão:

Inclusão de bookmark

Se quiser dar uma olhada no código-fonte, está disponível no meu repositório GitHub. Se quiser contribuir, faça fork, modifique e depois faça pull request. Toda ajuda será bem vinda 😉

A ferramenta PrettyFaces oferece muitos outros recursos avançados. Para quem se interessou, vale à pena aprofundar nela. O que você achou? Conhece outra ferramenta melhor? Compartilhe sua opinião!

Anúncios


8 Responses to “Pretty URL com JSF 2 e Demoiselle 2”

  1. é legal. o único problema é mais um arquivo xml pra editar. Já deu uma olhada no VRaptor? O VRaptor utiliza essas friendly urls e a configuração é através de annotations.

  2. 4 rafikdabahia

    Já estou usando nos meus projetos! Hehhe muito massa

  3. 5 Marcelo J. Both

    Nossa que bacana, não vejo problema algum em usar xml para fazer a configuração. Estava a procura de algo nesse sentido. vlw

  4. Fiz uma modificação no código-fonte para dar o seguinte comportamento:

    – tela de novo registro: /bookmark/new
    – tela de listagem: /bookmark
    – tela de edição do registro 5: /bookmark/5

    Quem quiser ver o que mudei: https://github.com/zyc/lab/commit/8fdcc99981f585de3445b059f01154ccbbd36531

    Já atualizei o post com isto!!! 😉

  5. Interessante, mas será q a performance não cai um pouco não? é mais um filtro de http.

    • A questão é: será que este possível tipo de perda de performance é significativo? Será que vale à pena ganhar esta facilidade em detrimento de uma possível perda de performance? Será que esta possível baixa performance da aplicação estaria realmente atribuída a isto? Enfim, é uma grande e velha discussão. Nada que possamos concluir sem experimentos, infelizmente…


E aí, o que você achou? Comenta aí...

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 )

Imagem do Twitter

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

Foto do Facebook

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

Foto do Google+

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

Conectando a %s