Como usar scriptlets para chamar método da classe DAO?

15 respostas
G

Fala pessoal!

Tô com uma dúvida quanto a obter os dados do banco numa página JSP, pois já tenho o seguinte código funcionando dentro dela e gostaria de remover para não ter sql na JSP:

<sql:setDataSource
         driver="org.postgresql.Driver"
         url="jdbc:postgresql://localhost:5432/Oblivion"
         user="postgres"
         password="12345"
         var="dataSource" />

    <%--  Consulta via SQL todos os registros da
          tabela Curso --%>
    <sql:query var="produtos" dataSource="${ dataSource }">
        select * from produto order by descricao
    </sql:query>

Tentei algumas coisas do tipo:

<% ProdutoDAO dao = new ProdutoDAO(); %>
<% dao.carregar(); %>

Mas o Eclipse sempre acusa algum erro, alguém sabe a forma certa de usar tag para rodar um select pela classe DAO numa página JSP?

Abraço!

15 Respostas

D

Oi,

Dentre as duas coisas que você fez, a primeira é a menos pior. Por favor, faça bem a você e a quem vai (talvez) manter o seu código. Não coloque código java dentro do jsp (usando <%%>, etc…).

Você quer os dados para montar uma tabela?
Diga o que você quer fazer, fica mais fácil te dar uma sugestão.

[]´s

G

Olá David!
Quero rodar um select no banco para popular uma tabela, é esta:

<div id="caixa">


   <h3>Cadastro de Produtos</h3>

    <%-- Cria conexão com banco de dados --%>

	
	<% ProdutoDAO dao = new ProdutoDAO(); %>
	<% dao.carregar(); %>
	
	<sql:setDataSource
         driver="org.postgresql.Driver"
         url="jdbc:postgresql://localhost:5432/Oblivion"
         user="postgres"
         password="12345"
         var="dataSource" />

    <%--  Consulta via SQL todos os registros da
          tabela Curso --%>
    <sql:query var="produtos" dataSource="${ dataSource }">
        select * from produto order by descricao
    </sql:query>
    

    <div>

    <table align="center" class="centraliza">
    <tr>
    <th width="5">C&oacute;digo</th>
    <th width="410">Descri&ccedil;&atilde;o</th>
    <th width="60">Quantidade</th>
    <th width="5">Estoque</th>
    <th width="50">Alterar</th>
    <th width="50">Excluir</th>
    </tr>

    <c:forEach var="linha" items="${ produtos.rows }">


    <tr class="centraliza">
        <td>${ linha.codigo }</td>
        <td>${ linha.descricao }</td>
        <td>${ linha.quantidade }</td>
        <td>${ linha.estoque }</td>



        <td><button
            onclick="javascript:atualizar(
                      '${linha.codigo}',
                      '${linha.descricao}',
                      '${linha.quantidade}',
                      '${linha.estoque}',
                      'alt');"><img
             src="imagens/alterar.jpg"
             alt="alterar produto: ${linha.codigo}"></button></td>


        <td><button
            onclick="javascript:atualizar(
                     '${linha.codigo}',
                    '${linha.descricao}',
                    '${linha.quantidade}',
                    '${linha.estoque}',
                    'exc');"><img
             src="imagens/excluir.jpg"
             alt="excluir produto: ${linha.codigo}"></button></td>
    </tr>
    </c:forEach>
    </table>
    </div>  <!-- fim da div caixa -->

    <div id="botoes">
      <button
      onclick="document.location.href='incProduto.jsp';">Incluir Produto</button>
      <button
      onclick="document.location.href='index.jsp';">Retornar</button>
    </div>  <!-- fim da div botoes -->
D

Certo.
Vc não está usando nenhum framework mvc não é?
Bem, a primeira coisa que você pode fazer é criar apenas um datasource no seu container de servlets.
Vc está usando o tomcat?

G

Isso mesmo, uso o Tomcat e já possuo o método carregar na classe ProdutoDAO(), tava pensando em usar esse método para popular a tabela. Não estou usando nenhum framework, td na unha mesmo.

D

Ou melhor… Para não ficar amarrado a configuração do container, vc poderia fazer um servlet que faz a consulta para vc, retornando os dados do DAO e então processar o retorno usando alguma biblioteca javascript.
Vc conhece a jQuery?

D

Poste a classe Produto para eu ver. Ai monto um exemplo p/ vc.
O ProdutoDAO tbm.

G

Tenho a jquery aqui, mas não sei usar para esse tipo de consulta no banco. "/
Quanto a servlet, ela só inclui, exclui e altera, teria então que criar um request vindo do botão “cadastro” para que a servlet responda com um select?

G

Lá vai:

ProdutoDAO:

package DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import utils.Conexao;
import controler.ExcecaoOblivion;
import model.Produto;


public class ProdutoDAO {
	
    
    public void incluir(Produto produto) throws ExcecaoOblivion {
        try {        
            Connection db = Conexao.getConnection();
            PreparedStatement st =
                db.prepareStatement("INSERT INTO produto (descricao,quantidade,estoque) VALUES (?,?,?)");
                
            st.setString(1, produto.getDescricao());
            st.setInt(2, produto.getQuantidade().intValue());
            st.setInt(3, produto.getEstoque().intValue());
            st.executeUpdate();
            st.close();
            
        } catch (SQLException ex) {     
            if (ex.getSQLState().equals("23505")) {
                throw new ExcecaoOblivion("Erro de inclusão: produto duplicado.",0);
            }
        }
             catch(Exception ex ) {
                throw new ExcecaoOblivion("Erro na inclusão do produto. Código " +
                        ((SQLException) ex).getSQLState() + "\nDescricao " + ex.getMessage(),0);
           }
         
        
    }
    
    public void alterar(Produto produto) throws ExcecaoOblivion {
        try {
            Connection db = Conexao.getConnection();
            PreparedStatement st =
            db.prepareStatement("UPDATE produto SET descricao = ?,quantidade = ?,estoque = ? WHERE codigo = ? ");
            st.setString(1, produto.getDescricao());
            st.setInt(2, produto.getQuantidade().intValue());
            st.setInt(3, produto.getEstoque().intValue());
            st.setInt(4, produto.getCodigo().intValue());
            st.executeUpdate();
            st.close();
            
            
        } catch (SQLException ex) {
            if (ex.getSQLState().equals("23505")) {
                throw new ExcecaoOblivion("Erro de alteração: produto duplicado.",0);
            } else {
            throw new ExcecaoOblivion("Erro na alteração do produto. Código " + ex.getSQLState(),0);
            }
        }
    }
    
    public void excluir(Produto produto) throws ExcecaoOblivion {
        try {
            Connection db = Conexao.getConnection();
            PreparedStatement st =
            db.prepareStatement("DELETE FROM produto WHERE codigo = ? ");
            st.setInt(1, produto.getCodigo().intValue());
            st.executeUpdate();
            st.close();
            
        } catch (SQLException ex) {
            throw new ExcecaoOblivion("Erro na exclusão do produto. Código " + ex.getSQLState(),0);
        }
    }

    public void carregar(Produto produto) throws ExcecaoOblivion {
        
        try {
            Connection db = Conexao.getConnection();
            PreparedStatement st =
                db.prepareStatement("SELECT codigo,descricao,quantidade,estoque FROM produto where codigo = ? ORDER BY descricao");
                st.setInt(1, produto.getCodigo().intValue());
                ResultSet rs = st.executeQuery();
                
                if (rs.next()) {
                    produto.setCodigo(rs.getInt(1));
                    produto.setDescricao(rs.getString(2));
                    produto.setQuantidade(rs.getInt(3));
                    produto.setEstoque(rs.getInt(4));
                                        
                }                
            rs.close();
            st.close();
        } catch (SQLException ex) {
            throw new ExcecaoOblivion("Erro ao carregar um produto. Código " + ex.getSQLState() +
                    "\nDescricao "  + ex.getMessage(),0);
        }

    }
    
 }

Classe Produto:

package model;

public class Produto {
private Integer codigo;
private String descricao;
private Integer quantidade;
private Integer estoque;

public void setCodigo(Integer codigo) {
	this.codigo = codigo;
}
public Integer getCodigo() {
	return codigo;
}
public void setDescricao(String descricao) {
	this.descricao = descricao;
}
public String getDescricao() {
	return descricao;
}
public void setEstoque(Integer estoque) {
	this.estoque = estoque;
}
public Integer getEstoque() {
	return estoque;
}
public void setQuantidade(Integer quantidade) {
	this.quantidade = quantidade;
}
public Integer getQuantidade() {
	return quantidade;
}

}
D

Me dá uns 15 minutos, já lhe respondo.

G

Opa, valeu David!

D

Ok.

No seu DAO, adicione o seguinte método:

public List<Produto> listar() throws ExcecaoOblivion {

    List<Produto> lista = new ArrayList<Produto>();

    try {

        Connection db = Conexao.getConnection();
        PreparedStatement st =
                db.prepareStatement( "SELECT * FROM produto ORDER BY descricao" );
        ResultSet rs = st.executeQuery();

        if ( rs.next() ) {
            Produto produto = new Produto();
            produto.setCodigo( rs.getInt( 1 ) );
            produto.setDescricao( rs.getString( 2 ) );
            produto.setQuantidade( rs.getInt( 3 ) );
            produto.setEstoque( rs.getInt( 4 ) );
            lista.add( produto );
        }

        rs.close();
        st.close();
        db.close();

    } catch ( SQLException ex ) {

        throw new ExcecaoOblivion( "Erro ao carregar um produto. Código " + ex.getSQLState()
                + "\nDescricao " + ex.getMessage(), 0 );

    }

    return lista;

}
Na classe Produto, adicione o seguinte método:
public String toJson() {
    return "{" + 
        "codigo: " + codigo + ", " +
        "descricao: '" + descricao + "', " +
        "estoque: " + estoque + ", " +
        "quantidade: " + quantidade + ", }";
}
Crie um Servlet e mapeie da forma que você quiser. No exemplo vou mapear como /servlets/ListarProdutosServlet
public class ListarProdutosServlet extends HttpServlet {

    protected void processRequest( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException {

        response.setContentType( "text/json;charset=UTF-8" );
        PrintWriter out = response.getWriter();
        
        out.print( "{ successo: " );

        try {
            
            ProdutoDAO dao = new ProdutoDAO();
            StringBuilder dados = new StringBuilder();
            
            for ( Produto p : dao.listar() )
                dados.append( p.toJson() + ", " );
            
            out.print( "true, " );
            out.print( "dados: [ " );
            out.print( dados.toString() );
            out.print( "]" );

        } catch ( ExcecaoOblivion exc ) {
            
            out.print( "false, " );
            out.print( "mensagemErro: '" + exc.toString().replace( "\n", "\\n" ) + "'"  );

        } finally {
            out.print( "}" );
            out.close();
        }

    }

    @Override
    protected void doGet( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException {
        processRequest( request, response );
    }

    @Override
    protected void doPost( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException {
        processRequest( request, response );
    }

    @Override
    public String getServletInfo() {
        return "Lista os produtos...";
    }
}
Crie um JSP com seguinte conteúdo:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!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>Produtos...</title>
        <script type="text/javascript" src="${pageContext.request.contextPath}/javascript/jquery-1.3.2.min.js"></script>
        <script type="text/javascript">
            $( document ).ready( function() {
                // registra o evento click para o botão com id btnCarregar
                $( '#btnCarregar' ).click( function() {
                    
                    $.ajax({
                        dataType: 'json', // espera por dados no formato json (olhe o content type no servlet)
                        type: 'post', // envia a requisição via post
                        url: '${pageContext.request.contextPath}/servlets/ListarProdutosServlet', // url que vai retornar os dados
                        beforeSend: function( xmlHttp ) { // antes de fazer a requisição, muda o status
                            
                            $( '#status' ).html( 'Carregando...' );
                            
                            // limpa o conteúdo da tabela
                            $( '#conteudo' ).html( '' );
                            
                        },
                        complete: function( xmlHttp, textStatus ) { // quanto a requisição completa, muda de novo
                            
                            $( '#status' ).html( 'Pronto' );
                            
                        },
                        success: function( data, textStatus ) {
                            
                            // se o valor sucesso veio como true do servlet
                            if ( data.successo ) {
                                
                                // dados dos produtos no formato json (atributo dados do valor retornado pelo servlet
                                var p = data.dados;
                                
                                // itera pelos produtos
                                for ( var i = 0; i < p.length; i++ ) {
                                    
                                    // para cada produto, cria uma nova linha
                                    var linha = '<tr>' +
                                            '<td>' + p[i].codigo + '</td>' +
                                            '<td>' + p[i].descricao + '</td>' +
                                            '<td>' + p[i].estoque + '</td>' +
                                            '<td>' + p[i].quantidade + '</td></tr>';
                                        
                                    // adiciona a linha criada no corpot da tabela
                                    $( '#conteudo' ).append( linha );
                                    
                                }
                                
                                // se falso, mostra a mensagem de erro (que veio da exceção)
                            } else {
                                alert( data.mensagemErro );
                            }
                            
                        }
                        
                    });
                    
                });

            });
        </script>
    </head>
    <body>
        <table>
            <thead>
                <tr>
                    <th>Código</th>
                    <th>Descrição</th>
                    <th>Quantidade</th>
                    <th>Estoque</th>
                </tr>
            </thead>
            <tbody id="conteudo">

            </tbody>
        </table>
        <input id="btnCarregar" type="button" value="Carregar!"/>
        <p><span id="status">Pronto</span></p>
    </body>
</html>

A instrução ${pageContext.request.contextPath} em EL no documento obtém sempre o contexto da aplicação. Olhe o código gerado (exibir código fonte no navegador) para ver o que acontece.

Não se esqueça de colocar a jQuery (http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2.min.js) na pasta javascript (que deve ficar no mesmo nível do JSP criado). Essa parte da inserção do javascript vc pode fazer da forma q está acostumado. Mude somente o src da tag script lá no meta.

Testa ai e avisa se funcionou. Qualquer dúvida no código posta de novo ;)

G

Valeu David!
Fiz td, só falta rodar td ao clicar no menú “Cadastro”:

<li><a href="/Oblivion/cadastro.jsp"><span>Cadastro</span></a></li>

Olha como é a aplicação:

Pelo visto aquela página JSP de listar produtos não vai rolar, teria que fazer rodar td ao clicar ali no “Cadastro”.

D

Funcionou o que eu te passei Guevara?
Vc não precisa necessariamente do botão.
Encapsula o código que está dentro do evento em uma função e chama ela quando vc quiser carregar os produtos.

Olhe aqui:
<script type="text/javascript"> 

    function carregarProdutos() {
    
        $.ajax({
            dataType: 'json', // espera por dados no formato json (olhe o content type no servlet)
            type: 'post', // envia a requisição via post
            url: '${pageContext.request.contextPath}/servlets/ListarProdutosServlet', // url que vai retornar os dados
            beforeSend: function( xmlHttp ) { // antes de fazer a requisição, muda o status
                
                $( '#status' ).html( 'Carregando...' );
                
                // limpa o conteúdo da tabela
                $( '#conteudo' ).html( '' );
                
            },
            complete: function( xmlHttp, textStatus ) { // quanto a requisição completa, muda de novo
                
                $( '#status' ).html( 'Pronto' );
                
            },
            success: function( data, textStatus ) {
                
                // se o valor sucesso veio como true do servlet
                if ( data.successo ) {
                    
                    // dados dos produtos no formato json (atributo dados do valor retornado pelo servlet
                    var p = data.dados;
                    
                    // itera pelos produtos
                    for ( var i = 0; i < p.length; i++ ) {
                        
                        // para cada produto, cria uma nova linha
                        var linha = '<tr>' +
            '<td>' + p[i].codigo + '</td>' +
            '<td>' + p[i].descricao + '</td>' +
            '<td>' + p[i].estoque + '</td>' +
            '<td>' + p[i].quantidade + '</td></tr>';
        
                        // adiciona a linha criada no corpot da tabela
                        $( '#conteudo' ).append( linha );
                        
                    }
                    
                    // se falso, mostra a mensagem de erro (que veio da exceção)
                } else {
                    alert( data.mensagemErro );
                }
                
            }
            
        });
        
    }
    
    $( document ).ready( function() {
        
        // registra o evento click para o botão com id btnCarregar
        $( '#btnCarregar' ).click( function() {
            carregarProdutos();
        });
        
        // chama a função carregar produtos quando a página estiver pronta
        carregarProdutos();
    
    });

</script>

Bem, estou indo dormir. Depois posta ai o que deu que amanhã eu vejo.
[]´s

G

Obrigado pela força David, tô estudando o código aqui e fazendo umas mudanças para fazer rodar como eu quero, tô querendo colocar o carregarProfutos ali no botão cadastro ou quando a página de cadastro for chamada.
Assim que conseguir eu posto aqui como ficou.
Abraço!

D

Guevara:
Obrigado pela força David, tô estudando o código aqui e fazendo umas mudanças para fazer rodar como eu quero, tô querendo colocar o carregarProfutos ali no botão cadastro ou quando a página de cadastro for chamada.
Assim que conseguir eu posto aqui como ficou.
Abraço!

Legal Guevara
[]´s

Criado 21 de dezembro de 2009
Ultima resposta 22 de dez. de 2009
Respostas 15
Participantes 2