Método de validação no managed bean

Já é sabido de todos como é fácil implementar seu próprio custom validator em JSF, mas para quem não lembra segue os passos abaixo:

  1. Crie uma classe que implementa a interface Validator (javax.faces.validator.Validator);
  2. Implemente o método validate;
  3. Registre seu custom validator no faces-config.xml;
  4. Use a tag <f:validator /> no seu jsp;

Como vocês podem ver não há dificuldades em seguir estes passos básicos, contudo há momentos em que não se quer criar uma classe separada que implemente a interface Validator, logo temos uma segunda alternativa -mais simples- em que você pode implementar um método de validação no seu managed-bean contanto que você use a mesma assinatura do método validate da interface Validator. Seria algo como:

[SomeBackingBean.java]

public void validateEmail(FacesContext context,
    UIComponent toValidate, Object value) {
	String email = (String) value;

	if (email.indexOf('@') == -1) {
		((UIInput)toValidate).setValid(false);

		FacesMessage message = new FacesMessage("Invalid Email");
		context.addMessage(toValidate.getClientId(context), message);
	}
}

Este método então seria utilizado dentro de uma tag JSF através do atributo validator como abaixo:

<h:inputText id="email"
	value="#{SomeBackingBean.user.email}"
	validator="#{SomeBackingBean.validateEmail}"
	required="true">
</h:inputText>

Caso o valor do componente inputText seja inválido, ou seja, caso não seja um formato de endereço de e-mail válido, então será adicionado uma mensagem no faces context associado ao componente.

Bem simples não é? Mais fácil e menos trabalhoso que criar uma classe para cada tipo de validação customizada 😀 Eu aconselho utilizar-se desta segunda alternativa quando se tratar de validações específicas somente a uma view (tela) ou managed-bean, isto é, quando houver a necessidade de um custom validator que será utilizado em vários componentes e/ou telas então é melhor você usar a primeira alternativa implementando a interface Validator para não ter que reescrever código!

Mas fica uma pulga atrás da orelha..

Por que eu estou utilizando os parâmetros do método validateEmail() que estão associados ao componente inputText quando eu poderia utilizar-me diretamente da propriedade #{SomeBackingBean.user.email} já que meu método de validação está dentro do meu managed-bean?

Bem, você não pode fazer isso pois a validação ocorre antes que os valores dos componentes sejam vinculados ao modelo (na fase Update model values), neste momento o modelo é um estado desconhecido no ciclo de vida do JSF que somente será executado posteriormente caso não ocorra erros durante a fase de conversão e validação. Simplesmente pense neste método como sendo executado de uma objeto que implementa a interface Validator.

Como podem ver, o ciclo de vida do JSF é algo importante que temos que entender para podermos trabalhar de maneira mais adequada com a tecnologia.

Para entender melhor sobre converters e validators basta acessar este link !