Como passar argumentos para métodos de ManagedBeans no JSF

Estou tentando criar uma aplicação CRUD em JSF.

Antes de mais nada, vou relacionar as fontes que consultei até agora, que não esclareceram minha dúvida:

JavaServer Faces in Action
Mastering JavaServer Faces
StepByStepGuideForBuildingSimpleJSFApp
Core Java Server Faces
Introduction to Java Server Faces (JSF) (Sun ppt)

Bem, eu tenho uma base de dados de uma livraria. Basicamente estou tentando trabalhar com duas tabelas por enquanto, a de livros e a de gêneros. Não estou usando Hibernate ou JPA, tenho classes TO e classes DAO que usam JDBC mesmo.

A primeira tela da aplicação é a listagem dos livros.

Eu redirecionei a página inicial no web.xml:

<welcome-file-list>
<welcome-file>
faces/ListarLivros.jsp
</welcome-file>
</welcome-file-list>

O arquivo ListarLivros.jsp contém o código para listagem. Essa parte está funcionando.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h3>Livraria</h3>
        <f:view>
            <h:form>
                <h:commandButton value="Novo" action="#{LivroMB.incluir}"/>
            </h:form>
            <h:form>
                <h:dataTable value="#{ListaMB.livros}" var="livro" border="1"
                             first="#{ListaMB.primeira}" rows="5">
                    <h:column>
                        <f:facet name="header"><f:verbatim>Livro ID</f:verbatim></f:facet>
                        <h:commandButton value="#{livro.livro_id}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Titulo</f:verbatim></f:facet>
                        <h:outputText value="#{livro.titulo}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Autor</f:verbatim></f:facet>
                        <h:outputText value="#{livro.autor}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Editora</f:verbatim></f:facet>
                        <h:outputText value="#{livro.editora}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Gênero</f:verbatim></f:facet>
                        <h:outputText value="#{livro.genero.descricao}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Estoque</f:verbatim></f:facet>
                        <h:outputText value="#{livro.estoque}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><f:verbatim>Preço</f:verbatim></f:facet>
                        <h:outputText value="#{livro.preco}"/>
                    </h:column>
                </h:dataTable>

                <center>
                    <h:commandButton value="|<" action="#{ListaMB.primeiro}"/>
                    <h:commandButton value="<" action="#{ListaMB.anterior}"/>
                    <h:commandButton value=">" action="#{ListaMB.proxima}"/>
                    <h:commandButton value=">|" action="#{ListaMB.ultimo}"/>
                </center>
            </h:form>
        </f:view>
    </body>
</html>

A parte da paginação está OK, funcionando. O botão Incluir exibe um formulário em branco para inclusão.
Eu criei um botão na coluna de id porque quero que o usuário clique nele para editar o registro. Mas como eu passo o id do registro para o ManagedBean?

Tentei vincular o valor pela propriedade binding do commandButton com um atributo da classe LivroMB. Mas não funcionou. Quando clico no botão, o valor do atributo permanece nulo.

Os MBs usados são estes:

LivroMB

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package managedbean;

import dao.GeneroDAO;
import dao.LivroDAO;
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.html.HtmlCommandButton;
import models.LivroTO;
import javax.faces.component.html.HtmlInputText;
import javax.faces.model.SelectItem;
import models.GeneroTO;

/**
 *
 * @author Unam Power
 */

public class LivroMB {
    private GeneroDAO generoDao;
    private LivroDAO livroDao;
    private LivroTO livro;
    private LivroTO estadoLivro;
    private HtmlCommandButton botaoId;

    public HtmlCommandButton getBotaoId() {
        return botaoId;
    }

    public void setBotaoId(HtmlCommandButton botaoId) {
        this.botaoId = botaoId;
    }

    /** Creates a new instance of LivroManagedBean */
    public LivroMB() {
        livro = new LivroTO();
        livroDao = new LivroDAO();
        generoDao = new GeneroDAO();
    }

    public String incluir()
    {
        this.setLivro(new LivroTO());
        return "editar";
    }

public String editar(int livro_id)
    {
        this.setLivro(livroDao.find(livro_id));
        return "editar";
    }

    public String buscarLivro()
    {
        LivroDAO dao = new LivroDAO();

        livro = dao.find(livro.getLivro_id());

        livro = (livro == null ? new LivroTO() : livro);

        


        return null;
    }

    public String gravarLivro()
    {
        livroDao.save(livro);

        return null;
    }

    public String cancelar()
    {
        livro = estadoLivro;
        return "listar";
    }


    public LivroTO getLivro() {
        estadoLivro = livro;
        return livro;
    }

    public void setLivro(LivroTO livro) {
        this.livro = livro;
    }

    public List<SelectItem> getGeneros()
    {
        List<SelectItem> generos = new ArrayList<SelectItem>();

        List<GeneroTO> objGeneros = generoDao.listAll();

        for (GeneroTO generoTO : objGeneros) {
            generos.add(new SelectItem(String.valueOf(generoTO.getGenero_id()),generoTO.getDescricao()));
        }

        return generos;
    }

}

ListaMB

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package managedbean;

import dao.LivroDAO;
import java.util.ArrayList;
import javax.faces.component.html.HtmlCommandButton;

/**
 *
 * @author Unam Power
 */

public class ListaMB {
    private LivroDAO livroDAO;
    private ArrayList livros;
    private int primeira;
    private HtmlCommandButton botaoId;
    private String texto;

    public ListaMB(HtmlCommandButton botaoId) {
        this.botaoId = botaoId;
    }

    public HtmlCommandButton getBotaoId() {
        return botaoId;
    }

    public void setBotaoId(HtmlCommandButton botaoId) {
        this.botaoId = botaoId;
    }


    public String actionId()
    {
        String idBotao = botaoId.getValue().toString();
        texto = "Livro selecionado: "+idBotao;
        return null;
    }

    public int getPrimeira() {
        return primeira;
    }

    public void setPrimeira(int primeira) {
        this.primeira = primeira;
    }

    public String proxima()
    {
        primeira += 5;
        if (primeira >= livros.size()-5)
        {
            primeira = livros.size() - 5;
        }
        return null;
    }

    public String anterior()
    {
        primeira -= 5;
        if (primeira <0)
        {
            primeira = 0;
        }
        return null;
    }

    public String primeiro()
    {
        primeira = 0;
        return null;
    }

    public String ultimo()
    {
        primeira = livros.size()-5;
        return null;
    }

    /** Creates a new instance of TabelaBean */
    public ListaMB() {
        livroDAO = new LivroDAO();
        livros = livroDAO.listAll();
        primeira = 0;
    }

    public ArrayList getLivros() {
        return livros;
    }

    public void setLivros(ArrayList livros) {
        this.livros = livros;
    }

    

}




Eu não vi todo o seu código, porém se você quer passar um parametro, você pode usar a tag f:param.

Exemplo:

                     &lt;h:commandLink action="#{cidade.doExcluir}"&gt;
                            &lt;f:param name="id" value="#{cidade.id}" /&gt;
                      &lt;/h:commandLink&gt;

Espero ter ajudado

Você pode passar parâmetros utilizando < f:param
Pesquise sobre Converters
Aqui tem muita coisa boa

O JSF 2 vai permitir você passar parâmetros para as suas actions.
Aleluia irmãos |o|

edit: mas caso vc precise passar algum parâmetro que esteja unicamente na interface Web (a.k.a., JavaScript), vc também pode usar o a4j:actionparam.

O que você você quer fazer é pegar o valor da linha da tabela que você clicou não é? E aí então pegar o id do objeto.

A maneira mais correta de fazer isso é sempre trabalhar com o objeto da linha. Você vai chamar um método do bean por esse botão na coluna de id, e nele você pode pegar o objeto linha clicado pelo mapa de request. Quando você clica em uma linha de tabela em jsf, automaticamente você está inserindo esse objeto no escopo request. É aí que você vai pegá-lo.

Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
ObjetoSeu objeto = (ObjetoSeu) requestMap.get("Aqui você coloca o nome da propriedade 'var' do componente h:dataTable ");

E pronto, agora você tem o objeto armazenado em uma variável e pode trabalhar com ele da melhor maneira.

Lembre-se, quando trabalhar com java tenta usar orientação à objetos sempre.

Abraços

Obrigado pelas respostas. Avaliei todas, incluindo os links externos.

A solução do 22-Gers, como ele mesmo sugere, é mais elegante e foi a que eu implementei. Está funcionando perfeitamente, consegui fazer o formulário de edição.

Eu já tinha o atributo var=“livro” no <h:dataTable>, foi só implementar no método editar() do meu bean o código do 22-Gers.

Grato e que este post ajude outros.

Olá galera, peguei esse post pesquisando sobre um problema, e tenho um problema que talvez alguem de vcs possa me ajudar

Fiz uma tela de cadastro, um codigo que gera os telas do meu cadastro dinamicamente, ou seja, informo a minha tabela e o codigo monta minha tela…ate ai perfeito, tudo fuciona, passou para os objetos, nome, cores valores quando tudo necessario.

O meu problema é que no meu xhtml eu simplesmente chamo meu managedbean que cria a minha tela, e mais nada, nao crio no xhtml os objetos, labels, texts, nada disso…tudo é criado no meu managedbean.

Ai vem o problema, como eu faço para pegar os dados que esses objetos já criados vao receber por exemplo:

inputext1 = 01
inputext2 = joão

como eu faço para pegar esses dados… 01;joao…para poder gravar, (inserts/updates)…

obrigado