Dúvida com JSF + Facelets para submeter formulário

Fala galera, tudo bem?!

Realmente eu estou um tanto quanto perdido e se alguém puder me ajudar a sanar minhas dúvidas, eu ficarei muito feliz!

Seguinte: eu estou utilizando a tecnologia Facelets como forma de “templatizar” o desenvolvimento da aplicação na qual estou trabalhando. O problema é que não estou conseguindo de jeito nenhum fazer com que os dados dos inputText da interface sejam “setados” no bean correspondente! Aliás, até há pouco tempo, o botão que eu estava usando (commandButton) não estava funcionando “nem a custa de reza braba”! Eu até pensei em utilizar FacesContext como já vi no JSF in Action e também em alguns fóruns, mas eu não acredito que seja necessário utilizar FacesContext para um caso como o meu. De acordo com o Ciclo de Vida do JSF e de acordo com o estudo de tecnologias que eu fiz, eu escolhi JSF exatamente por esta “vinculação automática” entre os valores dos campos do formulário e o bean gerenciado. Mas simplesmente não estou conseguindo fazer isso funcionar. Algumas dúvidas:

  1. Para fazer com que os valores do formulário sejam “submetidos” às respectivas propriedades no bean, o commandButton tem de conter type=“submit” e tem de estar dentro do <h:form> que contém os campos que quero atualizar no bean? Porque se tiver, eu só consegui fazer ele funcionar com immediate=“true”. Mas com immediate=true, se eu entendi, pula todas as fases do ciclo de vida e não atualiza nada lá no bean;

  2. FacesContext só não deveria ter de ser usado quando eu quero alterar a interface dinamicamente?

  3. O botão que estou usando pode estar dentro de um outro <h:form>, dentro de um outro ui:define, no caso da utilização de Facelets?

Acho que é só por enquanto! Seguem os códigos usados nesta labuta:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!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:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:t="http://myfaces.apache.org/tomahawk"
      xmlns:c="http://java.sun.com/jstl/core">
  

	
    <ui:composition template="./template2.xhtml">
 
       <h:messages globalOnly="false" />       
        <ui:define name="menuAtributo">
        	<ul>
        		<li>Cadastro de Atributo</li>
        	</ul>
        
        </ui:define>
        
        <ui:define name="conteudoAtributo">
        
        <table>
        	<tr>
        		<td bgcolor="#B8CFE5"><b>Atributo</b></td> 
        		<td bgcolor="#EEEEEE"><b><a href="http://localhost:8080/EstudoJSF/cadastraRegra.jsf">Regra</a></b></td>
        		<td bgcolor="#EEEEEE"><b><a href="http://localhost:8080/EstudoJSF/cadastraAtributoSimples.jsf">Atributo Simples</a></b></td>
        		<td bgcolor="#EEEEEE"><b><a href="http://localhost:8080/EstudoJSF/cadastraAtributoComposto.jsf">Atributo Composto</a></b></td>
        		<td bgcolor="#EEEEEE"><b><a href="http://localhost:8080/EstudoJSF/cadastraIdiomas.jsf">Idiomas</a></b></td>
        	</tr>
        </table>
        
        <div style="overflow:auto; height:300px;">
                
        <!--  Utilizar tabela de dados do JSF para dar aparência para a tela -->
        
        
        <!-- Coloca SCROLL aqui. -->
        <h:form id="umForm">
        
        <table>
        	<tr>
        	<td>
        	<h:outputText value="Mnemonico Atributo"/><br/>
        	<h:inputText value="#{Atributo.mnemonico}" />
        	</td>
        	<td>
        	<h:outputText value="Aba"/><br/>
        	<h:inputText value="#{Atributo.aba}" />
        	</td>
        	</tr>
        	<tr>
        	<td>
        	<h:outputText value="Sequencial Atributo"/><br/>
        	<h:inputText value="#{Atributo.sequencial}">
        		<f:convertNumber />
        	</h:inputText>
        	</td>
        	<td>
        	<h:outputText value="Tipo Atributo"/><br/>
        	<h:selectOneMenu id="status" value="#{Atributo.tipoAtributo}">
    				<f:selectItems id="textoSelecao" value="#{Atributo.listaTiposAtributos}"/>
    			</h:selectOneMenu>
        	</td>
        	</tr>
        	
        	<tr>
        	<td>
        	<h:outputText value="Tipo Dominio"/><br/>
        	<h:selectOneMenu id="status" value="#{Atributo.tipoDominio}">
    				<f:selectItems id="textoSelecao" value="#{Atributo.listaDominios}"/>
    			</h:selectOneMenu>
        	</td>
        	<td>
        	<h:outputText value="Atributo Compositor"/><br/>
        	<h:inputText value="#{Atributo.atributoCompositor}" />
        	</td>
        	</tr>
        	
        	<tr>
        	<td>
        	<h:outputText value="Definido pelo Sistema"/><br/>
        	<h:selectOneMenu id="status" value="#{Atributo.definidoPeloSistema}">
    				<f:selectItems id="textoSelecao" value="#{Atributo.verdFalso}"/>
    			
    			</h:selectOneMenu>
        	</td>
        	<td>
        	<h:outputText value="Armazenado"/><br/>
        	<h:selectOneMenu id="status" value="#{Atributo.armazenado}">
    				<f:selectItems id="textoSelecao" value="#{Atributo.verdFalso}"/>
    			
    		</h:selectOneMenu>
        	</td>
        	</tr>
        	
        	
        	<tr>
        	<td>
        	<h:outputText value="Ocultar este Atributo?"/><br/>
        	<h:selectOneMenu id="status" value="#{Atributo.ocultar}">
    				<f:selectItems id="textoSelecao" value="#{Atributo.verdFalso}"/>
    			
    		</h:selectOneMenu>
        	</td>
        	</tr>
			</table>
			
			</h:form>      
        
        </div>
                
        </ui:define>
        
        <ui:define name="botoes">
        <center>
        <h:form>
        	  <h:outputText value="Uepa"/>   
        	   <h:commandButton type="submit" id="butao" value="Cadastrar Atributo" action="#{Atributo.cadastra}"/>
			 
        </h:form>
        </center>
        </ui:define>
      
      	
    </ui:composition>

</html>

Só como observação, o escopo do bean é SESSÃO, ok?!

Bean:

package beans;

import java.util.LinkedList;
import java.util.List;

import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

/**
 * Este vai ser o bean por tras do cadastro de um atributo.
 * Como o cadastro de atributo exige uma outra tela, e adequado que um bean diferente 
 * esteja associado a esta tela. No caso de atributos ja cadastrados,
 * tais dados serao adquiridos do banco de dados e mostrados em formato de tabela
 * na pagina de cadastro de entidade.
 * @author vvgneto
 *
 */
public class Atributo 
{
	private String mnemonico;
	private String aba; //como que o sistema atual faz referencia pra aba?
	private int sequencial;
	private String tipoAtributo;
	private String tipoDominio;
	private boolean atributoCompositor;
	private boolean definidoPeloSistema;
	private boolean armazenado;
	private boolean ocultar;
	//boolean oculto;
	private boolean editavel;
	private int cardMin;
	private int cardMax;
	private boolean parteChave;
	private boolean unico;
	private String regrasValidacao;
	private String regrasDerivacao;
	private String atributoLigacao;
	private String tipoSubject;
	private String tipoObserver;
	private String subject;
	private int tamanho;
	private int menorValor;
	private int maiorValor;
	private String valorDefault;
	private String mascaraEdicao;
	private String unidMedidaAtributo;
	private String extensao;
	private String aplicativo;
	private String plataforma;
	private String nomeClasseExecutavel;
	private String dadosEnumeracao;
	private String referencia;
	private String atributoReferencia;
	private String filtro;
	private String portugues;
	private String textAjudaPT;
	private String espanhol;
	private String textAjudaES;
	private String ingles;
	private String textAjudaIN;
	private String frances;
	private String textAjudaFR;
	
	public Atributo(){
		
		this.setMnemonico("ISTO");
	}
	
	
	public String getMnemonico() {
		return mnemonico;
	}

	public void setMnemonico(String mnemonico) {
		this.mnemonico = mnemonico;
	}

	public String getAba() {
		return aba;
	}

	public void setAba(String aba) {
		this.aba = aba;
	}

	public int getSequencial() {
		return sequencial;
	}

	public void setSequencial(int sequencial) {
		this.sequencial = sequencial;
	}

	public String getTipoAtributo() {
		return tipoAtributo;
	}

	public void setTipoAtributo(String tipoAtributo) {
		this.tipoAtributo = tipoAtributo;
	}

	public String getTipoDominio() {
		return tipoDominio;
	}

	public void setTipoDominio(String tipoDominio) {
		this.tipoDominio = tipoDominio;
	}

	public boolean getAtributoCompositor() {
		return atributoCompositor;
	}

	public void setAtributoCompositor(boolean atributoCompositor) 
	{
		this.atributoCompositor = atributoCompositor;		
	}

	public boolean getDefinidoPeloSistema() {
		return definidoPeloSistema;
	}

	public void setDefinidoPeloSistema(boolean definidoPeloSistema) 
	{
		this.definidoPeloSistema = definidoPeloSistema;
		
		
	}

	public boolean getArmazenado() 
	{
		return armazenado;
	}

	public void setArmazenado(boolean armazenado) 
	{
		this.armazenado = armazenado;		
		
	}

	public boolean getOcultar() 
	{
		return ocultar;
	}

	public void setOcultar(boolean ocultar) 
	{
		this.ocultar = ocultar;
		
		
	}

	public boolean getEditavel() 
	{
		return editavel;
	}

	public void setEditavel(boolean editavel) 
	{
		this.editavel = editavel;		
		
	}

	public int getCardMin() {
		return cardMin;
	}

	public void setCardMin(int cardMin) {
		this.cardMin = cardMin;
	}

	public int getCardMax() {
		return cardMax;
	}

	public void setCardMax(int cardMax) {
		this.cardMax = cardMax;
	}

	public boolean getParteChave() {
		return parteChave;
	}

	public void setParteChave(boolean parteChave) 
	{
		this.parteChave = parteChave;
		
	}

	public boolean getUnico() 
	{
		return unico;
	}

	public void setUnico(boolean unico) 
	{
		this.unico = unico;
		
	}

	public String getRegrasValidacao() {
		return regrasValidacao;
	}

	public void setRegrasValidacao(String regrasValidacao) {
		this.regrasValidacao = regrasValidacao;
	}

	public String getRegrasDerivacao() {
		return regrasDerivacao;
	}

	public void setRegrasDerivacao(String regrasDerivacao) {
		this.regrasDerivacao = regrasDerivacao;
	}

	public String getAtributoLigacao() {
		return atributoLigacao;
	}

	public void setAtributoLigacao(String atributoLigacao) {
		this.atributoLigacao = atributoLigacao;
	}

	public String getTipoSubject() {
		return tipoSubject;
	}

	public void setTipoSubject(String tipoSubject) {
		this.tipoSubject = tipoSubject;
	}

	public String getTipoObserver() {
		return tipoObserver;
	}

	public void setTipoObserver(String tipoObserver) {
		this.tipoObserver = tipoObserver;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String sub) {
		subject = sub;
	}

	public int getTamanho() {
		return tamanho;
	}

	public void setTamanho(int tamanho) {
		this.tamanho = tamanho;
	}

	public int getMenorValor() {
		return menorValor;
	}

	public void setMenorValor(int menorValor) {
		this.menorValor = menorValor;
	}

	public int getMaiorValor() {
		return maiorValor;
	}

	public void setMaiorValor(int maiorValor) {
		this.maiorValor = maiorValor;
	}

	public String getValorDefault() {
		return valorDefault;
	}

	public void setValorDefault(String valorDefault) {
		this.valorDefault = valorDefault;
	}

	public String getMascaraEdicao() {
		return mascaraEdicao;
	}

	public void setMascaraEdicao(String mascaraEdicao) {
		this.mascaraEdicao = mascaraEdicao;
	}

	public String getUnidMedidaAtributo() {
		return unidMedidaAtributo;
	}

	public void setUnidMedidaAtributo(String unidMedidaAtributo) {
		this.unidMedidaAtributo = unidMedidaAtributo;
	}

	public String getExtensao() {
		return extensao;
	}

	public void setExtensao(String extensao) {
		this.extensao = extensao;
	}

	public String getAplicativo() {
		return aplicativo;
	}

	public void setAplicativo(String aplicativo) {
		this.aplicativo = aplicativo;
	}

	public String getPlataforma() {
		return plataforma;
	}

	public void setPlataforma(String plataforma) {
		this.plataforma = plataforma;
	}

	public String getNomeClasseExecutavel() {
		return nomeClasseExecutavel;
	}

	public void setNomeClasseExecutavel(String nomeClasseExecutavel) {
		this.nomeClasseExecutavel = nomeClasseExecutavel;
	}

	public String getDadosEnumeracao() {
		return dadosEnumeracao;
	}

	public void setDadosEnumeracao(String dadosEnumeracao) {
		this.dadosEnumeracao = dadosEnumeracao;
	}

	public String getReferencia() {
		return referencia;
	}

	public void setReferencia(String referencia) {
		this.referencia = referencia;
	}

	public String getAtributoReferencia() {
		return atributoReferencia;
	}

	public void setAtributoReferencia(String atributoReferencia) {
		this.atributoReferencia = atributoReferencia;
	}

	public String getFiltro() {
		return filtro;
	}

	public void setFiltro(String filtro) {
		this.filtro = filtro;
	}

	public String getPortugues() {
		return portugues;
	}

	public void setPortugues(String portugues) {
		this.portugues = portugues;
	}

	public String getTextAjudaPT() {
		return textAjudaPT;
	}

	public void setTextAjudaPT(String textAjudaPT) {
		this.textAjudaPT = textAjudaPT;
	}

	public String getEspanhol() {
		return espanhol;
	}

	public void setEspanhol(String espanhol) {
		this.espanhol = espanhol;
	}

	public String getTextAjudaES() {
		return textAjudaES;
	}

	public void setTextAjudaES(String textAjudaES) {
		this.textAjudaES = textAjudaES;
	}

	public String getIngles() {
		return ingles;
	}

	public void setIngles(String ingles) {
		this.ingles = ingles;
	}

	public String getTextAjudaIN() {
		return textAjudaIN;
	}

	public void setTextAjudaIN(String textAjudaIN) {
		this.textAjudaIN = textAjudaIN;
	}

	public String getFrances() {
		return frances;
	}

	public void setFrances(String frances) {
		this.frances = frances;
	}

	public String getTextAjudaFR() {
		return textAjudaFR;
	}

	public void setTextAjudaFR(String textAjudaFR) {
		this.textAjudaFR = textAjudaFR;
	}
	
	public List<SelectItem> getListaTiposAtributos()
	{
		LinkedList<SelectItem> lista = new LinkedList<SelectItem>();
		
		lista.add(new SelectItem("ABA"));
		lista.add(new SelectItem("BASICO"));
		lista.add(new SelectItem("COMPOSTO"));
		lista.add(new SelectItem("ENUMERADO"));
		lista.add(new SelectItem("EXECUTAVEL"));
		lista.add(new SelectItem("ID_PROPRIO"));
		lista.add(new SelectItem("OBJ_EXTERNO"));
		lista.add(new SelectItem("OBJ_INTERNO"));
		
		return lista;
	}
	
	
	public List<SelectItem> getListaDominios()
	{
		LinkedList<SelectItem> lista = new LinkedList<SelectItem>();
		
		lista.add(new SelectItem("ALFANUMERICO"));
		lista.add(new SelectItem("BOOLEANO"));
		lista.add(new SelectItem("COMPOSTO_AGRUPADOR"));
		lista.add(new SelectItem("COMPOSTO_COMPLEXO"));
		lista.add(new SelectItem("COMPOSTO_LISTA"));
		lista.add(new SelectItem("COMPOSTO_SIMPLES"));
		lista.add(new SelectItem("DATA"));
		lista.add(new SelectItem("DECIMAL"));
		lista.add(new SelectItem("INTEIRO"));
		lista.add(new SelectItem("MOEDA"));		
		
		return lista;
	}
	
	public List<SelectItem> getVerdFalso()
	{
		LinkedList<SelectItem> lista = new LinkedList<SelectItem>();
		
		lista.add(new SelectItem("Verdadeiro"));
		lista.add(new SelectItem("Falso"));
		
		return lista;
	}
	
		
	/**
	 * TODO Metodo cadastrar.
	 * Este metodo encapsula um atributo que esta sendo cadastrado.
	 * Logo, ele deve ter um metodo cadastrar associado para poder chamar
	 * a persistencia e mandar os dados para baixo.
	 */
	public String cadastra()
	{			
		
		this.vai();
		
		return "cadastro";
		
	
		
	}
	
	public void vai()
	{
		System.out.println("Valor de sequencial: " + this.sequencial);
		System.out.println("Owa! Aqui vai levar o atributo cadastrado para baixo na pilha de camadas");
		System.out.print("Alguem...");
		System.out.println("Valor de ocultar este atributo: " + this.ocultar);
		System.out.println("Mnemonico: " + this.getMnemonico());
		
	}
	
	
	

}

Valdemar, o commandButton tem que estar dentro do mesmo form, e deve funcionar mesmo sem o immediate=true. Deve ter dado erro na validação de algum campo. Põe o faces-config.xml pra gente dar uma olhada melhor.

Valeu!

Fala camarada!

Então c quer dizer que quando a validação falha a atualização/submissão dos dados não acontece? Mas o estranho e ruim é que os erros simplesmente não são lançados na linha de comando e nem mesmo na tela do navegador, sei lá!

Eu não usei nenhum validador nem padrão nem customizado! E eu cheguei a desenvolver um conversor booleano por causa de um campo booleano que na tela tem os valores da lista (Verdadeiro/Falso). Vou postá-lo aqui também para que dê uma olhada!

Ah, e queria saber também se você tem alguma sugestão de tutorial sobre conversores e validadores que seja melhor que aquele JSF for non-believers, que eu num gostei daquele não!

Faces:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
			
  <!-- from project setup -->
  <application>
    <view-handler>
      com.sun.facelets.FaceletViewHandler
    </view-handler>    
  </application>
  
  <!-- our NumberBean we created before -->
  <managed-bean>
    <managed-bean-name>NumberBean</managed-bean-name>
    <managed-bean-class>beans.NumberBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>min</property-name>
      <value>1</value>
    </managed-property>
    <managed-property>
      <property-name>max</property-name>
      <value>10</value>
    </managed-property>
  </managed-bean>
  
  <managed-bean>
    <managed-bean-name>PersonBean</managed-bean-name>
    <managed-bean-class>beans.PersonBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
   
   <managed-bean>
    	<managed-bean-name>Atributo</managed-bean-name>
    	<managed-bean-class>beans.Atributo</managed-bean-class>
    	<managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
  
  
  <managed-bean>
    <managed-bean-name>GeraEntidade</managed-bean-name>
    <managed-bean-class>beans.GeraEntidade</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
  
  <managed-bean>
    <managed-bean-name>CadastraBean</managed-bean-name>
    <managed-bean-class>beans.CadastraBeanFacesConfig</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
  
  <managed-bean>
    <managed-bean-name>CadastraDominioEnumerado</managed-bean-name>
    <managed-bean-class>beans.CadastraDominioEnumerado</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
    <managed-bean>
    <managed-bean-name>TabelaAtributos</managed-bean-name>
    <managed-bean-class>beans.TabelaAtributos</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
  
  
  
  <!-- going from guess.xhtml to response.xhtml -->
  <navigation-rule>
    <from-view-id>/guess.xhtml</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/response.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>

  <!-- going from response.xhtml to guess.xhtml -->
  <navigation-rule>
    <from-view-id>/response.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
      <to-view-id>/guess.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>
  
  <!-- indo de principal.xhtml to principal.xhtml -->
  <navigation-rule>
    <from-view-id>/principal.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>teste</from-outcome>
      <to-view-id>/principal.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>
  
  <navigation-rule>
    <from-view-id>/cadastraAtributo.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>cadastro</from-outcome>
      <to-view-id>/cadastraAtributo.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>
  
  
  <converter>
  	<converter-id>conversorBooleano</converter-id>
  	<converter-class>beans.ConversorVerdadeiroFalso</converter-class>
  </converter>
  

</faces-config>

Conversor Booleano Doidão:

package beans;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

public class ConversorVerdadeiroFalso implements Converter
{

	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) throws ConverterException 
	{
		
		if(arg2.compareTo("Verdadeiro") == 0){return new Boolean(true);}
		
		if(arg2.compareTo("Falso") == 0){return new Boolean(true);}
		
		return new Boolean(true);
		
		
	}

	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)throws ConverterException 
	{
		if(arg2 instanceof Boolean)
		{
			if(arg2.toString().compareTo("true") == 0)
				return "trueOu";
			if(arg2.toString().compareTo("false") == 0)
				return "falsen";
		}		
		
	    return "falsio";
	}
	

}

Fala cara!

Isso mesmo. Quando alguma validação falha, o processamento é interrompido. Aí o método cadastra num vai funcionar.
…Tô sem muita coisa pra poder ajudar aqui, mas certamente posso arrumar umas coisas legais pra vc quando eu chegar no trabalho amanhã. Mostro uns conversores que a gente fez que ficaram legais.

Por enquanto, já que a mensagem de erro não apareceu no console (por falar nisso, vc deu uma olhada no console e/ou no log do servidor WEB?), sugiro que vc coloque apenas uma propriedade String na página pra ver se vai dar certo com pelo menos essa. Botar uma pra funcionar já é alguma coisa :wink:

E aqui vai uma dica pro teu conversor de booleano doidão (gostei do “doidão” :D):

if("Verdadeiro".equals(arg2)){return new Boolean(true);} // colocar a string antes ajuda a evitar NullPointerException if("Falso".equals(arg2)){return new Boolean(true);}

if(arg2 instanceof Boolean) { if(Boolean.TRUE.equals(arg2)) return "trueOu"; else return "falsen"; }

Outra coisa, em JSF, se seu action retornar “” (string vazia) ou null, ele redireciona pra mesma página. Já reduz umas linhas de configuração.

Amanhã mando uma ajudinha melhor!
Falou!

Valdemar, talvez vc já os tenha visto, mas dá uma sacada nesses links:

http://www.laliluna.de/javaserver-faces-converter-tutorial.html

Falou!

Fala Gregório! hauahuahuauuahua! Curtiu o doidão! hauhauhauhahua!

Então, cara obrigado pelas dicas porque eu não sabia realmente da questão de null ou string vazia para retornar à mesma página! Realmente economiza linhas!

Agora: eu percebi que haviam vários ids repetidos então procurei colocar um id único para cada um e colocar o botão dentro do mesmo form para que ele seja submetido. Aí deu este erro aqui! C por acaso sabe do que se trata?! Eu não acredito que para fazer JSF funcionar tem que usar necessariamente algum elemento UIComponent implementado por baixo em Java. Para mim só precisava fazer isso quando fosse uma interface dinâmica, sei lá!

Aqui estão os erros que estão sendo lançados agora:

description The server encountered an internal error () that prevented it from fulfilling this request.

exception 

javax.servlet.ServletException
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:209)


root cause 

java.lang.IllegalArgumentException
	javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:149)
	javax.faces.component.UISelectOne.matchValue(UISelectOne.java:141)
	javax.faces.component.UISelectOne.validateValue(UISelectOne.java:114)
	javax.faces.component.UIInput.validate(UIInput.java:645)
	javax.faces.component.UIInput.executeValidate(UIInput.java:849)
	javax.faces.component.UIInput.processValidators(UIInput.java:412)
	javax.faces.component.UIForm.processValidators(UIForm.java:170)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:912)
	javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:342)
	com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:78)
	com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)
	com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:90)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)


note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.

Desde já muito obrigado pelos toques!

Flws!

Fala cara!

Pela mensagem, é erro de validação de alguma das listas. Põe só a lista de booleanos pra rodar. Na criação da coleção, constrói assim:

[code] public List getVerdFalso()
{
LinkedList lista = new LinkedList();

     lista.add(new SelectItem(true, "Verdadeiro"));  
     lista.add(new SelectItem(false, "Falso"));  
       
     return lista;  
 }[/code]

Tira as outras listas da página pra ver se essa vai funcionar. Se der certo, as outras vc cria da mesma forma, criando os objetos SelectItem com o primeiro parâmetro sendo o valor real, e o segundo sendo o texto que é exibido no componente HTML.

E, realmente, vc só vai precisar mexer com coisas do tipo UIComponent e demais classes do JSF se for pra coisas um pouco mais caprichadas. Pro que vc quer, não deve precisar.

Tenta aí e diz o q acontece.

Falou!

Fala Gregório!

Cara, c ganhou minha admiração viu?!
Sim, para resolver o problema bastava fazer como você mesmo disse!

Uma última dúvida: para renderizar a interface, se o construtor é vazio, os valores que vão aparecer nas listas são os da lista dentro do get, correto?!
Eu não preciso de criar uma variável private para guardar as listas por exemplo porque vou acessar apenas um estado da lista por vez, correto?! Então, basta a outra variável que é referenciada dentro de selectOneMenu, certo?!

São perguntas, acredito eu, retóricas!

De qualquer forma, quero agradecer muito porque suas dicas foram bastante valiosas! Muito obrigado pela ajuda! Consegui, enfim, resolver meu problema!

Até mais!

Fala, cara!

Justamente! Se na página estiver assim:

<h:selectOneMenu id="status" value="#{Atributo.ocultar}"> <f:selectItems id="textoSelecao" value="#{Atributo.verdFalso}"/> </h:selectOneMenu>

o JSF vai procurar, na classe que defino o tipo do bean Atributo, pelo método getVerdFalso(). Não precisa ter a propriedade nem iniciar nada no construtor. Basta que existe um método que siga o padrão JavaBeans no método get. E tem que ter a variável que vai receber o resultado da lista.

Algumas vezes é útil ter em uma variável. Por exemplo, imagine que vc tem um serviço como o Facebook, com milhares de contas sendo criadas a todo instante. Toda vez que alguém for criar um cadastro, vai ter que informar o país, por exemplo. Imagina montar uma lista com 200 países com new SelectItem() pra toda nova contra de usuário… É melhor já ter essa lista numa variável e retorná-la. No seu caso, no entanto, não é necessário.

Então… sugiro que vc continue nesse ramo. JSF tem muito a crescer e muito problema cabuloso e muitas chatisses vão deixar de existir na versão 2. Começa a querer incluir outros componentes na página, como os da apache (Tomahawk e outros) e uns mais legais, como o ICEFaces (esse é mó viagem).

Fico bastante feliz por ter ajudado :slight_smile:
Boa sorte aí!
Falou!