No TDC2011 (SP) além de me divertir e aprender bastante também apresentei, na trilha Java EE, a palestra: "RichFaces 4: Desenvolvimento Web com JSF2 mais rico". Iniciei a palestra comentando sobre as vantagens em adotar uma suíte de componentes UI (User Interface) terceira no desenvolvimento de aplicativos web com JavaServer Faces versão 2.
Mas o foco da palestra foi explorar os novos recursos do RichFaces 4, uma das mais famosas suítes para desenvolvimento JSF, a nova versão recentemente lançada completamente compatível com JSF 2.Nesse post vou explorar um pouco mais algumas uma funcionalidades citadas na palestra: RichFaces Client Side Validation (CSV), a validação de campos do RichFaces 4 com Bean Validation. Mais uma vez utilizei nossa cobaia para experiências com JSF, o ScrumToys.
Bean Validation no lado cliente
O novo componente rich:validator, do RichFaces 4, pode ser vinculado a componentes inputs em uma tela para aplicar validações de acordo com as restrições definidas através das anotação do Bean Validation.
O Bean Validation é uma especificação Java EE 6 (JSR 303) que padroniza um mecanismo de validação, aplicado a objetos que seguem o modelo JavaBean, configurados a partir de anotações. Os containers que implementam o Java EE 6 utilizam um provider do Bean Validation, como o Hibernate Validator por exemplo. Mas nesse caso as validações são processadas pelo container, no lado servidor.
Com o rich:validator as validações do Bean Validation ocorrem no browser, no lado cliente. O código a seguir demonstra trechos da entidade Story, com as anotações demarcando validações que deverão ser aplicadas no cadastro da entidade. Nesse caso o nome não pode ser nulo, deve conter no mínimo 3 e no máximo 5 caracteres, enquanto a prioridade dever estar entre 1 e 5. Veja:
(Story.java)
//...
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
@Entity
//... definicao de tables e namedqueries da entidade
public class Story extends AbstractEntity implements Serializable {
@NotNull
@Size(min=3, max=60)
@Column
private String name;
@Min(value=1)
@Max(value=5)
private int priority;
//... outros atributos e os metodos da entidade
}
No próximo trecho de código o uso do rich:validator dentro os inputs das propriedades name e priority da entidade Story. Um detalhe importante para a validação funcionar corretamente é utilizar em conjunto o componente rich:message ou rich:messages, responsáveis por exibir na tela as mensagens caso a validação reclame:
(\story\create.xhtml)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html 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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<ui:composition template="/template.xhtml">
...
<ui:define name="content">
<h:form styleClass="scrumForm" id="createStoryForm">
<h:panelGrid columns="3">
<h:outputLabel value="Name:" for="itName"/>
<h:inputText id="itName"
value="#{storyManager.currentStory.name}">
<rich:validator />
</h:inputText>
<rich:message for="itName" styleClass="errorMessage"/>
<h:outputLabel value="Priority:" for="itPriority" />
<h:inputText id="itPriority"
value="#{storyManager.currentStory.priority}">
<rich:validator />
</h:inputText>
<rich:message for="itPriority" styleClass="errorMessage"/>
...
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</html>
Ao renderizar a página no browser, o código javascript gerado para a validação na camada cliente será parecido com o demonstrado a seguir (apliquei uma formatação básica pra melhorar a visualização):
(javascript gerado na tela de cadastro de uma nova Story)
function createStoryForm_3AitName_3Av(event,id,e,da){
var p={da:da,
v:[{f:RichFaces.csv.validateSize,
p:{"min":3,"max":60},
m:{"detail":"size must be between 3 and 60",
"severity":0,
"summary":"size must be between 3 and 60"}},
{f:RichFaces.csv.validateRequired,
p:{},
m:{"detail":"may not be null",
"severity":0,
"summary":"may not be null"}}]};
RichFaces.csv.validate(event,id,e,p);
}
function createStoryForm_3AitPriority_3Av(event,id,e,da){
var p={da:da,
c:{f:RichFaces.csv.convertInteger,p:{},
m:{"detail":"{2}: ''{0}'' must be a number between \u002D2147483648 and 2147483647 Example: {1}",
"severity":0,
"summary":"{2}: ''{0}'' must be a number consisting of one or more digits."} },
v:[{f:RichFaces.csv.validateMin,
p:{"value":1},
m:{"detail":"must be greater than or equal to 1",
"severity":0,
"summary":"must be greater than or equal to 1"}},
{f:RichFaces.csv.validateMax,p:{"value":5},
m:{"detail":"must be less than or equal to 5",
"severity":0,
"summary":"must be less than or equal to 5"}}]};
RichFaces.csv.validate(event,id,e,p);
}
$(document).ready(function() {
new RichFaces.ui.Message("createStoryForm:j_idt68",
{"forComponentId":"createStoryForm:itName",
"showSummary":false,
"showDetail":true} )
new RichFaces.ui.Message("createStoryForm:j_idt74",
{"forComponentId":"createStoryForm:itPriority",
"showSummary":false,
"showDetail":true})
});
Analisando o restante do html é possível identificar que as 2 funções javascript são associadas ao evento onchange dos 2 inputs. Esse é o comportamento padrão do rich:validator, mas é possível customizar outro evento através da propriedade event, por exemplo:
(\story\create.xhtml)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html 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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
...
<h:outputLabel value="#{i18n['story.form.label.name']}:" for="itName"/>
<h:inputText id="itName"
value="#{storyManager.currentStory.name}">
<rich:validator event="keyup" />
</h:inputText>
<rich:message for="itName" styleClass="errorMessage"/>
...
</html>
Os validadores JSF, como por exemplo o f:validateRange, funcionam mesmo quando misturados ao mesmo input que usa o rich:validator, mas isso não é recomendado. Adotando Bean Validation a configuração para validar os dados de uma entidade pode ser reaproveitada em várias camadas do aplicação.
Caso não exista código lado cliente (javascript) registrado para uma determinada validação, o rich:validator executa a validação no lado servidor via Ajax (Ajax fall-backs). Outro exemplo do uso e mais detalhes sobre o rich:validator estam disponíveis na documentação do RichFaces 4.
Links complementares:
[]s
Eder Magalhães
www.yaw.com.br
twitter.com/youandwe
twitter.com/edermag


0 comentários:
Postar um comentário