Métodos de Validação em JSF – Parte V
Criando um componente de validação personalizado
Quando a validação não esta amarrada a lógica de negócio da aplicação, mas nenhum dos validadores padrão do JSF não é o suficiente.
Vamos implementar um componente personalizado de validação, para isso precisaremos de uma classe que implemente a interface Validator e possua um método chamado validate, único método definido pela interface.
void validate(FacesContext context, UIComponent componente,Object value)
Quando uma validação falha, devemos gerar uma FacesMessage que descreva o erro, construa uma ValidadorException e apresente-a:
if (vlPgto < vlMinimo) {
FacesMessage message = new FacesMessage(
"Pagamento abaixo do valor minimo aceitável:"
+ " (R$"
+ vlMinimo + ").");
throw new ValidatorException(message);
}
}
Crie um pacote chamado fatura.model e nele crie a classe FaturaBean conforme mostrado a seguir:
package fatura.model;
public class FaturaBean {
private String clienteNome;
private double valorPagto;
public String getClienteNome() {
return (clienteNome);
}
public void setClienteNome(String nome) {
this.clienteNome = nome;
}
public double getValorPagto() {
return (valorPagto);
}
public void setValorPagto(double valorPg) {
this.valorPagto = valorPg;
}
public String efetuarPagto() {
return ("success");
}
}
A classe FaturaBean tem dois atributos definidos como private e seus métodos de acesso (getters e setters) além do método efetuarPagto() que retorna uma string.
package fatura.control;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class Validacao implements Validator {
@Override //comente essa linha se estive usando jdk 1.4
public void validate(FacesContext context, UIComponent componente,Object value)
throws ValidatorException {
//Em uma situação real estes campos deveriam estar definidos como privados
double vlPgto = ((Double) value).doubleValue();
double vlMinimo = vlMinimoPgto();
if (vlPgto < vlMinimo) {
FacesMessage message = new FacesMessage(
"Pagamento abaixo do valor minimo aceitável:"
+ " (R$"
+ vlMinimo + ").");
throw new ValidatorException(message);
}
}
public double vlMinimoPgto() {
/** Em uma situação real este valor retornado seria
* originado de uma consulta ao banco de dados
*/
return (10.00);
}
}
Além disso, precisaremos de uma classe auxiliar ao validator para que através dela o validador seja reconhecido, nesse momento ela instancia a classe Validacao.
Crie em fatura.control a classe TagValidacao:
package fatura.control;
import javax.faces.validator.Validator;
import javax.faces.webapp.ValidatorTag;
import javax.servlet.jsp.JspException;
@SuppressWarnings("serial") //comente essa linha se estive usando jdk 1.4
public class TagValidacao extends ValidatorTag {
public TagValidacao() {
super();
setId("Validacao");
}
protected Validator createValidator() throws JspException{
return new Validacao();
}
}
No arquivo faces-config.xml vamos registrar a classe Validação no item validator, conforme o arquivo abaixo:
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<!—Configurando o Back Bean FaturaBean -->
<managed-bean>
<managed-bean-name>faturaBean</managed-bean-name>
<managed-bean-class>fatura.model.FaturaBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<!— Regras de validação -->
<navigation-rule>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/respostas/confirmacao.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<!-- Registrando o Validador -->
<validator>
<validator-id>valida</validator-id>
<validator-class>fatura.control.Validacao</validator-class>
</validator>
</faces-config>
A arquivo a seguir é o web.xml, se você estiver usando o NetBeans ou o Eclipse com algum algum plugin você não precisará fazer muitas modificações, contudo, caso seja necessário, altere o servlet-mapping:
<!-- servlet-mapping -->
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>MyFaces Application</display-name>
<!-- servlet -->
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- servlet-mapping -->
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<!-- The Usual Welcome File List -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
A seguir código do arquivo index.jsp :
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title></title>
</head>
<body>
<% response.sendRedirect("main.faces"); %>
</body>
</html>
A seguir vemos o código do arquivo main.jsp que será usado para entrada de dados do usuário para pagamento das faturas, vale destacar no código abaixo:
<h:inputText value="#{faturaBean.valorPagto}" id="valorPagto" required="true" >
<f:validator validatorId="valida" />
</h:inputText>
Explicando o código acima:
Na Tag <h:inputText> temos o campo required="true" como vimos no artigo anterior, esse campo faz com que o prenchimento do campo seja exigido, em value="#{faturaBean.valorPagto}" fazemos referência ao Back Bean FaturaBean e o atributo valorPagto mas o que realmente é novo pra nós é a linha:
<f:validator validatorId="valida" />
Informamos que o validatorId=”valida”, como pode ver no arquivo faces-config.xml nós registramos o nosso validator e informamos que o seu id seria: valida.
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<f:view>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD><TITLE>Pagamento de Faturas</TITLE>
<Link rel="STYLESHEET" href="./estilos/estilo.css" type="text/css">
</HEAD>
<BODY>
<h2>Pagamento de Fatura</h2>
<h:form>
<TABLE>
<TR>
<TD>Cliente: </TD>
<TD><h:inputText value="#{faturaBean.clienteNome}"
id="clienteNome" required="true">
</h:inputText>
<h:message for="clienteNome" styleClass="destaque"/></TD>
</TR>
<TR>
<TD>Valor a Pagar(R$):</TD>
<TD><h:inputText value="#{faturaBean.valorPagto}"
id="valorPagto" required="true" >
<f:validator validatorId="valida" />
</h:inputText><br />
</TD>
</TR>
<td colspan="2">
<h:message for="valorPagto" styleClass="destaque"/>
</td>
</TR>
<TR>
<td colspan="2">
<h:commandButton value="Confirmar"
action="#{faturaBean.efetuarPagto}"/>
</td>
</TR>
</TABLE>
</h:form>
</BODY>
</HTML>
</f:view>
Observe a Figura 2.
Crie o arquivo estilo.css em web/estilos:
.destaque {
font-weight: bold;
font-size:small;
font-family:arial,helvetica;
color: red;
background-color: yellow;
}
Crie em web/respostas o arquivo confirmacao.jsp (Figura 2)
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<f:view>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD><TITLE>Pagamento Recebido</TITLE>
</HEAD>
<BODY>
<H2>Pagamento Efetuado com Sucesso!</H2>
Caro(a) <b><h:outputText value="#{faturaBean.clienteNome}"/> </b> o seu pagamento no valor de <b>R$<h:outputText value="#{faturaBean.valorPagto}"/></b><br />
foi recebido com sucesso.
<p/>Obrigado.
</BODY>
</HTML>
</f:view>
Figura 1
Figura 2