Incompatibilidades do componente RichFaces: rich:fileUpload

Java, Java EE, Java Server Faces, Jboss Seam, RichFaces 4 Comments »

Estes últimos dias estive testando o componente “rich:fileUpload“. O componente é bastante interessante, porém é bastante sensível. Encontrei incompatibilidades com componentes do próprio richfaces, do myfaces e com o seam framework.

Até o momento verifiquei que usar o componente “rich:fileUpload” dentro do componente “rich:simpleTogglePanel”. Todos os testes que eu realizei ele não chama o evento definido em fileUploadListener. Até onde eu percebi me parece que o parâmetro que o “rich:fileUpload” usa para controlar o envio dos arquivos é perdido quando ele está dentro do “rich:simpleTogglePanel“.

Outro problema do componente é a incompatibilidade da versão 3.2.0 com o Seam Framework. Seguindo um comportamento semelhante ao do problema acima o evento definido no fileUploadListener não é chamado. Pelo que eu vi no JIRA havia problemas com o ciclo de vida do Seam, porém estes problemas já foram solucionados.

Havia também problemas com o envio de diversos arquivos ao mesmo tempo. Todos estes problemas também foram corrigidos.

A dica é: se você estiver usando o Seam Framework e o RichFaces 3.20 e pensar em usar o rich:fileUpload, atualize para as versões:
Seam 2.0.2 Cr1 (ou superior)
RichFaces 3.2.1 (Sugiro pegar a versão mais recente)
API
Implementação
User Interface

Jboss Seam - Getting started: Navigation Cases!

Java, Java EE, Java Server Faces, Jboss Seam No Comments »

No post Jboss Seam - Getting started: Page Actions, eu havia mostrado um caso simples de listagem e edição de notícias. Mas há casos exigem a criação casos de navegação para que não haja erros na execução.

Voltando ao exemplo de cadastro de notícias, o que aconteceria se o usuário por engano digitar um código que não existe na URL: /news/EditNews.jsf?newsId=9? Bom a página de edição apareceria com o formulário em branco ou geraria uma exceção.

A solução para este caso seria, caso o método gere um OUTCOME de erro, redireciona para a página de edição. Veja o exemplo:


<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages
http://jboss.com/products/seam/pages-2.0.xsd">

<page view-id="/news/EditNews.xhtml">
<param name="newsId" value="#{newsBean.news.newsId}"/>
<action execute="#{newsBean.loadNewsById(newsBean.news.newsId)}"/>

<rule if-outcome="error">
<redirect view-id="/news/list.xhtml"/>
</rule>
</page>
</pages>

Assim, caso o identificador for nulo ou inválido a action loadNewsById retornará o outcome error. Assim, a execução será redirecionada a página lista.xhtml evitando que erros sejam gerados e evitando quebra de dados no formulário. Simples não?

Jboss Seam - Getting started: Page Actions!

Java, Java Server Faces, Jboss Seam 4 Comments »

Um dos grandes problemas que os desenvolvedores JSF tem é lidar basicamente com 2 situações relacionadas com GET: Passar parâmetros e executar ações via GET. Vou dar dois exemplos clássicos:
1° - Você tem um sistema de cadastro de notícias. Dentro deste sistema você tem uma página que faz a listagem das notícias cadastradas. Para listar estas notícias cadastradas assim que carregasse a página você tinha duas saídas: uma seria fazer o controle no método get de seu datatable:
- No Managed Bean


private List<News> newsList;
...
public List<News> getNewList() {
if (newsList == null) {
newsList = myService.listNews();
}
return newsList;
}

Na página seria algo:


<h:dataTable value="#{newBean.newsList}">
<!-- colunas da tabela -->
</h:dataTable>

A outra forma você teria que criar a ação de listagem e para acessar a página você teria que chamar a página de um componente jsf: um menu ou um botão que fizesse uma requisição post invocando a ação.

Usando o recurso de Page Actions do Jboss Seam você não precisa mais usar estas “soluções alternativas” para executar ações e passar parâmetros para um Managed Bean via GET. Dentro de seu projeto o Seam irá reconhecer todos arquivos xml que sigam o padrão: *.page.xml ou o arquivo pages.xml dentro da pasta WEB-INF. Veja um exemplo do arquivo:


<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages
http://jboss.com/products/seam/pages-2.0.xsd">
<page view-id="/news/list.xhtml"
action="#{newsBean.listNews}"
conversation-required="false"/>

<page view-id="/news/EditNews.xhtml">
<param name="newsId" value="#{newsBean.news.newsId}"/>
<action execute="#{newsBean.loadNewsById(newsBean.news.newsId)}"
if="#{newsBean.news.newsId != null}"/>
</page>
</pages>

O código acima chama a ação JSF listNews antes de renderizar a página /news/list.jsf, que pode ser chamada via GET ou POST. O mesmo acontece para a edição de notícias /news/EditNews.jsf?newsId=9. Primeiro será vinculado o valor do parâmetro newsId com propriedade newsBean.news.newsId e após será chamada a ação loadNewsById que carrega a notícia recebendo como parâmetro o identificador da notícia.

Sem dúvida nenhuma o recurso de Page Actions é bem legal para se trabalhar com JSF. Vale a pena usar! Em breve mostrarei mais dicas de Page Actions!

Jboss Seam - Getting started: Validação de formulário

Java, Java Server Faces, Jboss Seam No Comments »

O Jboss Seam tem um suporte bem útil para validação de formulários. Ele pode ser integrado com o Hibernate Validator. Esta integração trás vantagens e desvantagens. A vantagem é que simplifica o desenvolvimento, através de anotações nas entidades é possível que os valores da entidade sejam validados. Por outro lado a aplicação fica dependente do Hibernate Validator para validar os dados. Em casos de validação simples, atende perfeitamente, mas para casos complexos é necessário a validação em lógica de negócio, e a nível de design da aplicação não sei até onde usar o Hibernate Validator é vantajoso.

Para a utilização da validação das entidades dentro da página basta colocar a tag:


<s:validateAll>
<!-- Todo os os componentes JSF inseridos aqui
dentro serão validados -->
</s:validateAll>

Outro recurso é o suporte a templates do Facelets que facilitam a padronização de: Rótulos, Componente de Entrada (Caixa de Texto, Caixa de seleção, Botões, etc) e as mensagens relacionadas ao componente. A seguir segue um exemplo de template:


<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:s="http://jboss.com/products/seam/taglib">

<div>

<s:label styleClass="#{invalid?'msgErro':''}">
<ui:insert name="label"/>
<s:span styleClass="required" rendered="#{required}">*</s:span>
</s:label>

<span class="#{invalid?'msgErro':''}">
<s:validateAll>
<ui:insert name="Input"/>
</s:validateAll>
<h:graphicImage src="<font size="-1">#{facesContext.externalContext.request.contextPath}/</font>imagens/erro.gif" rendered="#{invalid}"/>
</span>

<s:message styleClass="msgErro"/>

</div>

</ui:composition>

Desta forma, todo campo obrigatório (atributo required=true) terá o * na frente do nome do componente. Caso contenha algum erro de validação, que deixa o componente com estado inválido, será mostrado o estilo: msgErro.

Para utilizar o template é necessário utiliza a tag s:decorate. Teremos que criar duas definições para o template: label e Input. Diversos exemplos do Jboss Seam não definem um nome para a parte relacionada ao Input, gerando duplicação de identificador de componentes quando estamos utilizando o recurso de templates do Facelets. O código ficaria semelhante ao abaixo:


<s:decorate id="NomeDecorator" template="/WEB-INF/templates/InputTemplate.xhtml">
<ui:define name="label">Nome:</ui:define>
<ui:define name="Input">
<h:inputText id="nome" value="#{meuBean.nome}" required="true">
<a:support event="onblur" reRender="NomeDecorator"/>
</h:inputText>
</ui:define>
</s:decorate>

Acima assumi que o template foi salvo com o nome InputTemplate.xhtml dentro do diretório templates dentro de web-inf. É importante salvar os templates dentro da pasta WEB-INF para proteger o acesso do usuário ao template.

Infelizmente o s:decorate não tem distinção aos tipos de mensagens JSF (Informação, Alerta, Erro, Fatal) das quais poderíamos colocar as mensagens de forma mais intuitiva para cada tipo de problema.

WP Theme & Icons by N.Design Studio
Assine Assine os comentarios