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 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) adocumentaçã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:
1 2 3 4 5 | < 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):
1 2 3 4 5 6 7 8 9 10 11 | < 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | < 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:
1 2 3 4 5 6 7 | < 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:
1 2 3 4 5 6 7 8 9 10 | < 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:
1 2 3 4 5 6 7 8 | @ViewController @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:
1 2 3 4 5 6 | @ViewController @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!
Autor: Cleverson Sacramento