Capturando e inserindo dados de uma jsp para um bean

9 respostas
jeverson

Caros colegas,

Apenas para efeitos didáticos, estou tentando capturar os dados de uma entidade em minha index.jsp. Consegui capturar os dados, porém não consigo setá-los no bean.
Abaixo os códigos.

index.jsp:
<html>
   <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
   <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
   <f:view>
      <head>
      	 <f:loadBundle basename="com.corejsf.messages" var="msgs" />
         <link href="styles.css" rel="stylesheet" type="text/css"/>
         <title>
         	<h:outputText value="#{msgs.pageTitle}"/>
         </title>
      </head>
      <body>
         <h:form>
            <h:dataTable value="#{customer.all}" var="customers"
               styleClass="customers" 
               headerClass="customersHeader" columnClasses="custid,name,custid,name,custid,name,custid">
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.customerIdHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.Cust_ID}"/>
               </h:column>
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.nameHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.Name}"/>
               </h:column>
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.phoneHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.Phone_Number}"/>
               </h:column>
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.addressHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.Street_Address}"/>
               </h:column>
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.cityHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.City}"/>
               </h:column>
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.stateHeader}"/>
                  </f:facet>
                  <h:outputText value="#{customers.State}"/>
               </h:column> 
               <h:column>
                  <f:facet name="header">
                     <h:outputText value="#{msgs.delete}"/>
                  </f:facet>
				<h:commandLink actionListener="#{customer.deleteRow}">
					<h:outputText value="excluir"/>
					<f:param id="excluir" name="excluir" value="#{customers}" />
				</h:commandLink>
			</h:column>              
            </h:dataTable>
         </h:form>
      </body>
   </f:view>
</html>
bean Name:
package com.corejsf;

public class Name {
	private int cust_ID;
	private String name;
	private String phone_Number;
	private String street_Address;
	private String city;
	private String state;
	private boolean delete=false;
	
	public Name(){		
	}
	
	public Name(int id, String name, String fone, String street, String city,
			String state) {		
		this.cust_ID = id;
		this.name = name;
		this.phone_Number = fone;
		this.street_Address = street;
		this.city = city;
		this.state = state;		
	}
	
	public int getId() { return cust_ID; }
	public void setId(int id) { this.cust_ID = id; }
	
	public String getName() { return name; }
	public void setName(String name) { this.name = name; }
	
	public String getFone() {return phone_Number; }
	public void setFone(String fone) { this.phone_Number = fone; }
	
	public String getStreet() { return street_Address; }
	public void setStreet(String street) { this.street_Address = street; }
	
	public String getCity() { return city; }
	public void setCity(String city) { this.city = city; }
	
	public String getState() { return state; }
	public void setState(String state) { this.state = state; }
	
	public boolean isDelete() { return delete; }
	public void setDelete(boolean delete) { this.delete = delete; }

}
CustomerBean
package com.corejsf;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.faces.component.UIParameter;
import javax.faces.event.ActionEvent;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;
import javax.sql.DataSource;

public class CustomerBean {
   private Connection conn;
   private Name name;
   
   public Name getName() { return name; }
   public void setName(Name name) {this.name = name; }

   public void open() throws SQLException, NamingException {
      if (conn != null) return;
      Context ctx = new InitialContext();
      DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mydb");
      conn = ds.getConnection();
   }
   
      
   public Result getAll() throws SQLException, NamingException {
      try {
         open();
         Statement stmt = conn.createStatement();         
         ResultSet result = stmt.executeQuery("SELECT * FROM Customers");         
         return ResultSupport.toResult(result);         
      } finally {
         close();
      }
   }
   
   public void deleteRow (ActionEvent event){
	   UIParameter parameter = (UIParameter) event.getComponent().findComponent("excluir");
	   Name name = (Name)parameter.getValue();
	   System.out.println("String: " + name.getName());
	   	   
   }
    
   
   public void close() throws SQLException {
      if (conn == null) return;
      conn.close();
      conn = null;
   }  
}

ao chamar o método deleteRow (através do link "excluir" na minha jsp) o seguinte erro surge:
SEVERE: 'java.lang.ClassCastException' when invoke action listener '#{customer.deleteRow}'

Porém, imprime normalmente os dados da linha selecionada na tabela ao implementar o método deleteRow da seguinte forma:
public void deleteRow (ActionEvent event){
	   UIParameter parameter = (UIParameter) event.getComponent().findComponent("excluir");
	   String name = parameter.getValue().toString();
	   System.out.println("String: " + name);	   	   
}

Alguma dica!?!?!?

Desde já agradeço!

9 Respostas

rolemberg

senão estou muito enganado esse erro que esta dando no deleteRow(ClassCastException), ocorre porque o tipo não é UIParameter e sim o seu Bean.

jeverson

Caro Rolember, não entendi ao certo o q vc disse, + fiz assim:

public void deleteRow (ActionEvent event){ Name name = (Name) event.getComponent().findComponent("excluir"); }

porém a API não aceita esse tipo de cast (Cannot cast from UIComponent to Name)

Teria + alguma idéia?!?!

Grato!

rolemberg

qual tipo de objeto vc retornar neste metodo: getAll()

A

Amigo no seu método getall, ele retorna uma lista de customers, entào na recuperaÇào da linha vc tem que fazer um “cast” de customers e nào de name…
Mas eu uso um DataModel para preencher as tabelas de JSF, inclusive para resgatar os beans…

DataModel x= new ListDataModel("sualista de objectos");

E quando vc quiser buscar o valor:

Entidade f = (Entidade) x.getRowData();
jeverson
Rolemberg o método getAll retona um objeto do tipo Result; recebo os dados do BD através de um ResultSet em seguida o converto para Result
public Result getAll() throws SQLException, NamingException {
      try {
         open();
         Statement stmt = conn.createStatement();         
         ResultSet result = stmt.executeQuery("SELECT * FROM Customers");         
         return ResultSupport.toResult(result);         
      } finally {
    	  close();
      }
}

Caro Androdana, como dito acima, o retorno da método getAll é do tipo Result, não o seto em nenhuma classe java ou bean da minha aplicação. Na index.jsp eu acesso os dados pelos nomes da coluna da tabela do meu BD. A classe q está setada no manegedBean do faces-config.xml é a classe CustomerBean e o método chamado para o preechimento do dataTable é, como já observado por vcs, é o getAll.

Caso eu quisesse receber somente o id do cliente, por exemplo, bastava eu passar na tag f:param value="#{customers.Cust_ID}"
(já fiz esse teste e deu certo). Como eu passo value="#{customers}" nessa msma tag eu recebo os dados do cliente, caso compravado pela impressão do retorno do método parameter.getValue().toString;

Seguindo ainda seu exemplo (se eu entendi corretamente) fiz o seguinte:
public DataModel getAll() throws SQLException, NamingException {
      try {
         open();
         Statement stmt = conn.createStatement();         
         ResultSet result = stmt.executeQuery("SELECT * FROM Customers"); 
         model = new ResultSetDataModel(result);
         return model;         
      } finally {
    	  //close(); COMENTEI ESSA LINHA PQ SE A CONEXÃO FOSSE FECHADA DAVA PAU
      }
}
   
public void deleteRow (ActionEvent event){
	   UIParameter parameter = (UIParameter) event.getComponent().findComponent("excluir");	   
	   model = (ResultSetDataModel) parameter.getValue();
	   Name name1 = (Name) model.getRowData();	  
	   System.out.println("String: " + name1.getName());
}

Porém não deu certo, pois o cast para model ñ foi aceito.
Tbm tentei fazendo o cast direto do retorno de model.getRowData para name e ñ deu...

public void deleteRow (ActionEvent event){	   
	   Name name1 = (Name) model.getRowData();	  
	   System.out.println("String: " + name1.getName());
}

alguma dica a mais?!?!

jeverson

Implementei a seguinte solução:

na index.jsp a passagem de parâmetros ficou assim:
<h:commandLink actionListener="#{customer.deleteRow}">
        <h:outputText value="excluir"/>
        <f:param id="id" name="id" value="#{customers.Cust_ID}" />
        <f:param id="name" name="name" value="#{customers.Name}" />
	<f:param id="phone" name="phone" value="#{customers.Phone_Number}" />
	<f:param id="street" name="street" value="#{customers.Street_Address}" />
	<f:param id="city" name="city" value="#{customers.City}" />
	<f:param id="state" name="state" value="#{customers.State}" />
</h:commandLink>
e no CustomerBean o método deleteRow ficou assim:
public void deleteRow (ActionEvent event){
        Name name = new Name();
        UIParameter parameter = (UIParameter) event.getComponent().findComponent("id");
	name.setId(Integer.parseInt(parameter.getValue().toString()));
	   
	parameter = (UIParameter) event.getComponent().findComponent("name");
	name.setName(parameter.getValue().toString());
	   
	parameter = (UIParameter) event.getComponent().findComponent("phone");
	name.setFone(parameter.getValue().toString());
	   
	parameter = (UIParameter) event.getComponent().findComponent("street");
	name.setStreet(parameter.getValue().toString());
	   
	parameter = (UIParameter) event.getComponent().findComponent("city");
	name.setCity(parameter.getValue().toString());
	   
	parameter = (UIParameter) event.getComponent().findComponent("state");
	name.setState(parameter.getValue().toString());
	  
}

Contudo, ñ achei q isso seja eficiente solução, visto que o atributo parameter pode receber todos os dados da linha selecionada.
O q ñ sei fazer é atribuir os valores recebidos à um objeto da classe Name

Alguma dica???

jeverson

Alguma idéia amigos?!?!

A

Jeverson vc pegou a idéia o que faltou foi implementa-la melhor…
Não fiz essa implementaçào com JDBC para ter os métodos prontos para te mostrar (uso o JPA/Hibernate), mas a classe getAll poderia ficar assim:

public DataModel getAll() throws SQLException, NamingException {  
      try {  
        open();  
        Statement stmt = conn.createStatement();           
        ResultSet result = stmt.executeQuery("SELECT * FROM Customers");   
        List<Customers> lista=result;
       model = new ResultSetDataModel(lista);  
       return model;           
    } finally {  
        //close(); COMENTEI ESSA LINHA PQ SE A CONEXÃO FOSSE FECHADA DAVA PAU  
     }  
 }

na sua página index poderia retirar o parâmetro id=excluir que não é preciso… ficando assim:

...
 <h:form>  
             <h:dataTable value="#{customer.all}" var="customers"  
                styleClass="customers"   
                headerClass="customersHeader" columnClasses="custid,name,custid,name,custid,name,custid">  
                <h:column>  
                   <f:facet name="header">  
                      <h:outputText value="#{msgs.customerIdHeader}"/>  
                   </f:facet>  
                   <h:outputText value="#{customers.Cust_ID}"/>  
                </h:column>  
                <h:column>  
                   <f:facet name="header">  
                      <h:outputText value="#{msgs.nameHeader}"/>  
                   </f:facet>  
                   <h:outputText value="#{customers.Name}"/>  
                </h:column>  
                <h:column>  
                   <f:facet name="header">  
                      <h:outputText value="#{msgs.phoneHeader}"/>  
                   </f:facet>  
                   <h:outputText value="#{customers.Phone_Number}"/>  
                </h:column>  
                <h:column>  
                   <f:facet name="header">  
                      <h:outputText value="#{msgs.addressHeader}"/>  
                   </f:facet>  
                   <h:outputText value="#{customers.Street_Address}"/>  
                </h:column>  
                <h:column>  
                  <f:facet name="header">  
                     <h:outputText value="#{msgs.cityHeader}"/>  
                   </f:facet>  
                  <h:outputText value="#{customers.City}"/>  
               </h:column>  
                <h:column>  
                  <f:facet name="header">  
                     <h:outputText value="#{msgs.stateHeader}"/>  
                   </f:facet>  
                   <h:outputText value="#{customers.State}"/>  
                </h:column>   
               <h:column> 
                    <f:facet name="header">    
                    <h:outputText value="#{msgs.delete}"/>  
                 </f:facet>  
                <h:commandLink actionListener="#{customer.deleteRow}">  
                  <h:outputText value="excluir"/>                      
               </h:commandLink>  
             </h:column>                
             </h:dataTable>  
...

já o outro método poderia ser assim:

public void deleteRow (ActionEvent event){  
        Customers c=(Customers) model.getRowData();
        Name name1 = c.getName();      
        System.out.println("String: " + name1.getName());  
 }

Checa por aí e faça as adaptaÇòes que julgar necessárias…
Abra

jeverson

Caro androdana,

Meu PC tava (e ainda está) bixado, soh hj vi sua msg. Assim q der vou
implementar essa solução e posto e resultado aki no fórum!

Mto obrigado pela atenção!

abração!

Criado 30 de novembro de 2009
Ultima resposta 9 de dez. de 2009
Respostas 9
Participantes 3