URL Amigáveis com Seam 2.1
Marcos Sousa | March 16, 2009Desenvolver aplicações com URL amigáveis em projetos JSF não é uma tarefa fácil. Porém ao utilizar o Seam, esta tarefa é muito facilitada. A versão 2.1 traz a integração nativa com o URLRewrite, simplicando ainda mais o desenvolvimento.
Meu objetivo neste post é mostrar as diferenças para implementação da mesma funcionalidade na versão 2.0 e a versão 2.1. Até a versão 2.1 era necessario (sem acento mesmo, dentro da reforma ortográfica) a criação de um Adapter. Vejamos como era feito, há até uma vídeo aula publicada sobre o assunto, primeiro vamos ao Adapter, necessário para fazer com que o URLRewriter resolva as URLs:
@Startup
@Scope(ScopeType.APPLICATION)
@Name("seamUrlRewriterFilter")
@BypassInterceptors
@Filter(within="org.jboss.seam.web.ajax4jsfFilter")
@Install(classDependencies="org.tuckey.web.filters.urlrewrite.UrlRewriteFilter",
precedence=Install.APPLICATION)
public class SeamUrlRewriterFilter extends AbstractFilter {
private UrlRewriteFilter urlRewriteFilter;
private Map initParameters;
public void init(FilterConfig filterConfig) throws ServletException {
urlRewriteFilter = new UrlRewriteFilter();
urlRewriteFilter.init(new FilterConfigWrapper(filterConfig, getInitParameters()));
}
public Map getInitParameters() {
return initParameters;
}
public void setInitParameters(Map initParameters) {
this.initParameters = initParameters;
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
urlRewriteFilter.doFilter(arg0, arg1, arg2);
}
private class FilterConfigWrapper implements FilterConfig {
private FilterConfig delegate;
private Map parameters;
public FilterConfigWrapper(FilterConfig config, Map parameters) {
this.delegate = config;
this.parameters = parameters;
}
public String getFilterName() {
return delegate.getFilterName();
}
public String getInitParameter(String arg0) {
if (parameters.containsKey(arg0)) {
return (String) parameters.get(arg0);
} else {
return (String) delegate.getInitParameter(arg0);
}
}
public Enumeration getInitParameterNames() {
Enumeration[] enumerations = {delegate.getInitParameterNames(),
Collections.enumeration(parameters.entrySet())};
return new EnumerationEnumeration(enumerations);
}
public ServletContext getServletContext() {
return delegate.getServletContext();
}
}
}
Você pode estar pensando: porque não declarar o filtro diretamente no web.xml? Precisamos garantir que ele seja executado após filtro do RichFaces, através da anotação @Filter(within=”org.jboss.seam.web.ajax4jsfFilter”). Também é importante que este filtro esteja dentro do contexto seam. Para que este Adapter funcione adequadamente, devemos registrá-lo no arquivo component.xml para que as URL’s sejam interpretadas.
<component name="seamUrlRewriterFilter" class="jm.seamtest.core.SeamUrlRewriterFilter" precedence="30"> <property name="initParameters"> <key>logLevel</key> <value>DEBUG</value> <key>statusEnabled</key> <value>false</value> </property> </component>
Já na versão 2.1, todas estas configurações não são mais necessarias. Basta adicionar esta tag no arquivo de configurações do seam, components.xml:
<web :rewrite-filter view-mapping="*.seam" />
Vamos imaginar como exemplo de URL amigável, a url usada neste blog para visualização de posts: /ano/mes/dia/titulo-uuid. Vamos analisar como era as configurações nas versões anteriores, a configuração do padrão de url era realizado diretamente no arquivo de configurações nativo do URLRewrite:
<rule enabled="true">
<from casesensitive="true">^/([0-9]{4})/([0-9]{2})/([0-9]{2})/([A-Z0-9]+[A-Za-z0-9]*)?$</from>
<to>/post/showpost.seam?ano=$1&mes=$2&dia=$3&tituloUUID=$4</to>
</rule>
O URLRewrite, exige do desenvolvedor conhecimentos de expressões regulares. Além do mapeamento da URL, é necessário vincular os parâmetros passados pela URL, uma das formas é usando Page Actions:
<page view-id="/post/showpost.xhtml">
<param name="ano" value="#{viewPostBean.ano}" />
<param name="mes" value="#{viewPostBean.mes}" />
<param name="dia" value="#{viewPostBean.dia}" />
<param name="tituloUUID" value="#{viewPostBean.tituloUuid}" />
<action execute="#{viewPostBean.show}" />
</page>
Na versão 2.1, não é mais necessária a configuração nativa, tudo que precisamos é de uma simples tag para mapear a url dentro da Page Action.
<page view-id="/post/showpost.xhtml">
<rewrite pattern="/{ano}/{mes}/{dia}/{tituloUUID}"/>
<param name="ano" value="#{viewPostBean.ano}" />
<param name="mes" value="#{viewPostBean.mes}" />
<param name="dia" value="#{viewPostBean.dia}" />
<param name="tituloUUID" value="#{viewPostBean.tituloUuid}" />
<action execute="#{viewPostBean.show}" />
</page>
O padrao de URL “/{ano}/{mes}/{dia}/{tituloUUID}” pode é traduzido em /post/showpost.xhtml?ano=2009&mes=03&dia=16&tituloUUID=url-amigavel. Neste caso todas as variáveis entre chaves são transformadas em parâmetros HTTP. Simples não?






Muito bom! Na versão 2.0, seria mais simples, porém inadequado, utilizar o arquivo de configuração urlrewrite.xml. A outra maneira de fazer isto nesta versão exige muito código por parte do desenvolvedor. E agora, com poucas linhas em arquivos xml, podemos fazer a mesma coisa.
Velho, ótimo tutorial.
Queria te perguntar uma coisa, existe alguma forma de “esconder” a página que foi chamada da URL.
Exemplo, quando eu digito http://www.blablalbla.com.br ele acaba direcionado para http://www.blablalbla.com.br/home.seam, esse home.seam teria como deixa ele sem aparecer?