Validações JSF

17 respostas
fantacone

Olá Caros amigos…

Seguinte, quando queremos validar um campo no JSF podemos utilizar os <f:validateXXX>… até aí tudo bem, o problema é quando você pode ter um campo == NULL no banco de dados. Pois o JSF nunca converte vazio para NULL, mas sim para zero(no meu caso estou utilizando a validação para Long)…

<h:inputText size="6" value="#{gprsController.gprsTela.nrIntervaloAngulo}" id="gprs_intervalo_angulo">
       <f:validateLongRange minimum="10" maximum="180" />
</h:inputText>

Ou seja, supondo que o usuário não digite um valor, eu deveria receber o dado como NULL e não como zero, pois futuramente uma regra de negócio irá avaliar se o campo no banco é igual a NULL…

Resumindo… Se o usuário não digitar valor no campo, quero receber o atributo como NULL…

Alguém sabe???

Valew…

17 Respostas

nel

Bom dia!

Além de validators o JSF oferece os converters.
Crie um converter customizado e caso o valor seja 0, como você mesmo citou, seta o mesmo para ‘null’.

Só um detalhe, essa consideração, na minha opinião, só deve ser levada em consideração caso você utilize o valor 0 para alguma outra função, caso contrário, poderia compreender que um valor 0 no seu bean é null, algo como:

campo == null || campo == 0.

Caso contrário, acho que a idéia do converter resolve sua necessidade.
Abraços.

fpastore

ou crie seu próprio validator… mais fácil talvez

fantacone

Olá Nel… primeiramente obrigado pela resposta…

faces-config.xml

<converter>  
    <converter-id>ConverterEmptyToNull</converter-id>   
    <converter-class>br.com.auteq.cbase.util.ConverterEmptyToNull</converter-class>   
</converter>

ConverterEmptyToNull.java

package br.com.auteq.cbase.util;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;


@FacesConverter(value="ConverterEmptyToNull")
public class ConverterEmptyToNull implements Converter{

	@Override
	public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
		
		if( value.equalsIgnoreCase("") ){
			value=null;
		}
		
		return value;
		
	}

	@Override
	public String getAsString(FacesContext facesContext, UIComponent component, Object obj) {
		
		return obj.toString();
		
	}

}

pagina.xhtml

<h:inputText converter="ConverterEmptyToNull" size="6" value="#{gprsController.gprsTela.nrIntervaloAngulo}" id="gprs_intervalo_angulo">
	<f:validateLongRange minimum="10" maximum="180" />
</h:inputText>

Ainda assim, no meu managed bean recebo o zero… e o pior é que por mais que eu quisesse verificar se for zero alterar para null no managed bean, eu não posso, pois as vezes o usuário pode ter digitado zero…

nel

O validator é simplesmente para validar, como o próprio nome diz e não para alterar um valor, concordas? :slight_smile:

Sobre o seu converter, use funções do Java, são melhores na minha opinião.
Assim: if( value.trim().isEmpty() )...

Sugiro o trim antes do isEmpty() para eliminar possíveis espaços em branco, pois se o usuário teclar space, ja nao iria funcionar, pois
“” é diferente de " " certo? :slight_smile:

Se persistir em não funcionar, pega o seu bean do contexto e seta diretamente o valor nele.
Se for um bean de request, por exemplo:

Seubean bean = (SeuBean) facesContext.getExternalContext().getRequestMap().get("seuManagedBean"); bean.setCampo(null);

Edit: creio que possa retirar a configuração que realizou no seu web.xml pois como trata-se de JSF 2.0, basta ter o annotion para que ele reconheça o seu converter. Outro detalhe, jogue um System.out.println() no seu converter e garanta que ele está sendo requisitado.

Abraços.

fantacone

Olá Nel…

Quanto ao Trim() ponto pra você… tem razão…

Já a pegar o bean da request, não seria um problema a única coisa é que são vários campos na mesma condição… daí toda vez que criasse um campo novo teria que mexer na regra do converter… concorda?

nel

Acreditava que era apenas um campo.
Ok, duas perguntas!

1 - Com a adição do método trim, funcionou ou o problema persiste?
2 - Não podes trabalhar com o valor sendo 0 ao invés do null?

Abraços.

evertonsilvagomesjav

Deixa eu perguntar, seu int nao pode ser Integer ou seu long ser Long?

fantacone

Boa Noite Amigos…

Primeiramente, muuuuito obrigado pela atenção… fico muito feliz com a ajuda de vocês…

Respondendo as perguntas:

1 - A mesma coisa… mesmo com o Trim não funcionou

2 - Então o problema é o seguinte… imagina que eu tenho uma distãncia em metros a ser percorrida, e quando essa distância for percorrida alguma coisa acontece… esse parâmetro define exatamente isso… Eu posso não ter uma distância definida, mas caso eu tenha ela tem que ser entre 10 e 180 por exemplo…

Então, já está como Wrapper… Integer, Long… e por aí vai…

Pelo que percebí a conversão é independente de usar um validador ou não… é meio que nativo do JSF…

Continuo na pesquisa… e conto com a ajuda de vocẽs…

Obrigado

nel

Entendo.

Para a sua problemática não vejo motivos para não usar o 0 assim como usaria o null.
Qual a diferença de percorrer uma distância null e uma distância 0?

Se eu digo á você: “Hoje andei 0 metros.”
Qual a conclusão? A minha seria que simplesmente eu fiquei parado.

Você pode tentar fazer da seguinte forma, pegar o nome do componente pelo UIComponent e através dele identificar em qual campo do seu bean você deve setar com null.
Mesmo assim, acredito que ainda chegue como 0 no seu Bean, mas não custa tentar.

Está longe de ser uma das melhores alternativas, pois, se tiver 10 campos terá 10 if´s e etc.
Só confirme se setar um campo diretamente no seu Bean como null, pegando do contexto, ele chega como null no seu Bean.
Bom, é isso. Se me surgir algo mais aprsentavél eu posto.

Apenas leve em consideração o que eu lhe disse no inicio.
Abraços!

fantacone

Olá… obrigado de novo !!!

Então… vou fazer os testes pegando do UIcomponente depois conto se deu certo…

Quanto a zero e null… você tem toda razão… o problema no meu caso é que um outro dispositivo(computador de bordo) é alimentado com esses dados, e ele pensa da seguinte maneira: Tenho que enviar uma informação para o servidor a cada quantos metros percorridos? 0 siginifica: A todo momento… null significa que está desativado o envio…

Aí você poderíamos pensar: Então por quê não colocar um checkbox na tela dizendo se está ativo ou não o rastreamento? Porquê o sistema atual(Delphi) já funciona dessa maneira… e mexer em regra de negócio por causa da tecnologia é barra…

Vlw e abraços

nel

fantacone:
Olá… obrigado de novo !!!

Então… vou fazer os testes pegando do UIcomponente depois conto se deu certo…

Quanto a zero e null… você tem toda razão… o problema no meu caso é que um outro dispositivo(computador de bordo) é alimentado com esses dados, e ele pensa da seguinte maneira: Tenho que enviar uma informação para o servidor a cada quantos metros percorridos? 0 siginifica: A todo momento… null significa que está desativado o envio…

Aí você poderíamos pensar: Então por quê não colocar um checkbox na tela dizendo se está ativo ou não o rastreamento? Porquê o sistema atual(Delphi) já funciona dessa maneira… e mexer em regra de negócio por causa da tecnologia é barra…

Vlw e abraços

E porque simplesmente se o valor for 0 você seta para null? :slight_smile:
Isso no seu Bean, pois ninguém vai digitar que percorreu 0 metros e se não digitar nada vem como 0, sendo assim, simplesmente se o valor for 0 set o mesmo como nulo.
Não resolveria?

Abraços.

fantacone

Oláááááá… obrigado pela atenção…

O pior é que o usuário pode digitar 0, nesse caso o sinal é enviado a todo instante… :shock:

nel

fantacone:
Oláááááá… obrigado pela atenção…

O pior é que o usuário pode digitar 0, nesse caso o sinal é enviado a todo instante… :shock:

Sabes o que tu pode fazer?
Crie um checkbox, se o usuário quiser digitar algo ele precisa “habilitar” esse campo.
Se ele habilitar, torne o campo como obrigatório, sendo assim, ou ele desabilita ou ele digita algum valor e caso ele digite 0, você envia o sinal a todo instante, como citou.

Podes usar o mesmo booleano do checkbox para habilitar e desabilitar o campo bem como para indicar se ele é ou não obrigatório.
O que acha?

Abraços.

fantacone

Opa… vlw de novo…

Então… é como eu tinha dito no começo… no sistema legado não percisa clicar em nada, apenas não colocar o valor… e os responsáveis pelo requisito querem que isso se mantenha…

ou seja… fu…

rs

Mas sem dúvida a idéia é boa…

gilvan.sfilho

Amigo, acho que encontrei uma solução para seu problema, não sei se das melhores mas pode funcionar.
Tente utilizar javascript para resolver seu problema, fazendo o seguinte:

Quando o usuário submeter o formulário verifique se no campo em questão existe algo digitado,
caso exista deixe como o usuário deixou,
caso não exista altere o valor para um número negativo. (pelo que você explicou acredito que não será possível utilizar valores negativos nesse campo)

Ai no bean você verificar se o número é negativo ou não.
Se for negativo seta ele como nulo =)

Não sei se vai funcionar, acredito que sim.

Abraços.

gilvan.sfilho

Amigo, implementei aqui o que falei e funcionou bacana, quando o usuário não digita nada o valor chega no bean como “-1”,
desta forma e possível setar o valor como nulo. Segue a solução:

pagina.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
        <script type="text/javascript" language="javacript">
            function submete() {
                    var valor = document.getElementById("form:valor").value;
                    if(valor == "") {
                        document.getElementById("form:valor").value = "-1";
                    }
            }
        </script>
    </h:head>
    <h:body>

        <h:form id="form">
            valor: <h:inputText id="valor" value="#{testeBean.valor}" />
            <h:commandButton value="Enviar" onclick="submete()" action="#{testeBean.acao}"/>
        </h:form>

    </h:body>
</html>

TesteBean.java

package br.ufac.scrum.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class TesteBean {

    private String valor;

    public String getValor() {
        return valor;
    }

    public void setValor(String valor) {
        this.valor = valor;
    }

    public String acao() {
        System.out.println("" + valor);
        return "pagina";
    }

}

É bom ressaltar que utilizei um atributo do tipo String no campo para que o mesmo não seja iniciado com valor igual a 0. Desta forma é possível fazer o que mencionei.
Espero que resolva o seu problema.

Abraços.

fernandogodoy18

fantacone:
Olá Nel… primeiramente obrigado pela resposta…

faces-config.xml

<converter>  
    <converter-id>ConverterEmptyToNull</converter-id>   
    <converter-class>br.com.auteq.cbase.util.ConverterEmptyToNull</converter-class>   
</converter>

ConverterEmptyToNull.java

package br.com.auteq.cbase.util;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;


@FacesConverter(value="ConverterEmptyToNull")
public class ConverterEmptyToNull implements Converter{

	@Override
	public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
		
		if( value.equalsIgnoreCase("") ){
			value=null;
		}
		
		return value;
		
	}

	@Override
	public String getAsString(FacesContext facesContext, UIComponent component, Object obj) {
		
		return obj.toString();
		
	}

}

pagina.xhtml

<h:inputText converter="ConverterEmptyToNull" size="6" value="#{gprsController.gprsTela.nrIntervaloAngulo}" id="gprs_intervalo_angulo">
	<f:validateLongRange minimum="10" maximum="180" />
</h:inputText>

Ainda assim, no meu managed bean recebo o zero… e o pior é que por mais que eu quisesse verificar se for zero alterar para null no managed bean, eu não posso, pois as vezes o usuário pode ter digitado zero…

Tenho um converter semelhante que no meu caso resolveu um problema bem parecido com o seu.

@FacesConverter(value="emptyToNullConverter")
public class EmptyToNullConverter implements Converter {

    public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
        if (value == null || value.trim().length() == 0) {
            if (component instanceof EditableValueHolder) {
                ((EditableValueHolder) component).setSubmittedValue(null);
            }
            return null;
        }
        return value;
    }

    public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
        return value == null ? null : value.toString();
    }

}
Criado 2 de março de 2011
Ultima resposta 7 de mar. de 2011
Respostas 17
Participantes 6