Validações JSF

17 respostas
F

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

N

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.

F

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

F

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…

N

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.

F

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?

N

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.

E

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

F

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

N

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!

F

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

N

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.

F

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

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

N

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.

F

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…

G

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.

G

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.

F

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