Problema com auditoria[RESOLVIDO]

Bom Dia, estou com mais uma dúvida aqui,desta vez é sobre Auditoria…

Bom, meu professor pediu pra mim criar essa classe para o meu sistema aqui…Aonde qualquer funcionario que inserir ou alterar no sistema, ele seja auditado…porém eu nao sei como fazer isso, ele me disse que não precisa criar servlet e nem usar o Hibernate, falou que eu só preciso instanciar o objeto dele la no servlet da tal pagina…exemplo…GerenciarClientes(esse é o servlet do cliente)…ai no Inserir, eu colocar o objeto da Auditoria la…ai quando eu entrar com o funcionario e inserir um cliente…vai criar um log na tabela Auditoria…e é ai que eu n sei como fazer isso…

Alguem pode me ajudar ?

Boa tarde Isaias_Barbosa,

Para seu sistema ter uma auditoria não é tão complexo. Se vc está utilizando banco de dados, basta criar uma tabela chamada AUDITORIA, com as colunas que vc está pretendendo gravar (usuário, data, por exemplo) e, quando o usuário tentar alterar ou inserir alguma informação, vc implementa um “insert into” que pegue as informações que vc precisa e executa logo após obter sucesso em inserir ou alterar uma informação. Algo como:

inserir (Usuario, Data) {

//seu insert
auditar(usuario, data);
}

O mesmo vale para o alterar.

Usa trigger direto no banco. Fazer pelo programa, ainda mais em Java, seja com ou sem Hibernate as chances de furo são bem maiores, quase que uma auditoria amadora.

Falei com o professor hoje e ele me passou esse código…

No caso aqui estou pegando o Inserir de um Cliente… no gerenciar cliente que fica no servlet…

switch (op) {
case “inserir”:
a.setAcao((“Inseriu Cliente:”+c.getNome()));
Funcionario f = (Funcionario) session.getAttribute(“atendente”);
a.setFuncionario(f);
c.inserir();
response.sendRedirect(“painel_atendente.jsp”);
break;

Eu criei uma tabela Auditoria no banco, ela tem os campos…Ação, datetime e o funcionario_id

Na classe DAO está assim o Inserir de Auditoria.

public class AuditoriaDAO extends DataBaseDAO{
public void inserir(Auditoria a) throws Exception{
String sql=“INSERT INTO auditoria (acao, now(), funcionario_id) VALUES(?,?,?)”;
this.conectar();
PreparedStatement pstm = conn.prepareStatement(sql);
pstm.setString(1, a.getAcao());
pstm.setInt(2, a.getFuncionario().getId());
pstm.execute();
this.desconectar();
}

Eu tinha dado uma olhada nesse Trigger, neste caso aqui, não precisa ser algo assim tão profissional…ele é apenas para mostrar no meu tcc do curso técnico…contando que esteja funcionando, já é algo bom…Mas vlw mesmo assim

Bom dia Isaias_Barbosa,

Fico feliz em ter contribuido de alguma forma. Boa Sorte.

Obrigado, pena que infelizmente não está funcionando…:frowning:

Esse é o codigo no Servlet de uma classe chamada GerenciarPlano, que é planos de pagamento…

No caso é na parte de Inserir…

case "inserir" a.setAcao(("Inseriu o Cliente:"+p.getNome())); Funcionario f = (Funcionario) session.getAttribute("funcionario"); a.setFuncionario(f); p.inserir(); break;

E aqui é a DAO da Auditoria

public class AuditoriaDAO extends DataBaseDAO{ public void inserir(Auditoria a) throws Exception{ String sql="INSERT INTO auditoria (acao, now(), funcionario_id) VALUES(?,?,?)"; this.conectar(); PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, a.getAcao()); pstm.setInt(2, a.getFuncionario().getId()); pstm.execute(); this.desconectar(); }

Mas, na hora em que eu vou inserir algo nesta tabela, ela inseri normal, mas nao manda os dados pra tabela de auditoria…

Será que poderia me ajudar pliss?

Vc está tentando executar a inserção com 3 question marks, quando deveriam ser apenas 2:
Errado, pois now() é uma função do DB, portanto não precisa de marcação:
INSERT INTO auditoria (acao, now(), funcionario_id) VALUES(?,?,?)

Logo:

Certo, pois somente acao e funcionario_id são parametros a serem marcados: 

INSERT INTO auditoria (acao, now(), funcionario_id) VALUES(?,?)

Por fim, ficaria desta forma:

public class AuditoriaDAO extends DataBaseDAO{

public void inserir(Auditoria a) throws Exception{
	//deve passar apenas 2 question marks, sendo now() uma função do DB
	String sql="INSERT INTO auditoria (acao, now(), funcionario_id) VALUES(?, ?)"; 
	this.conectar(); 
	PreparedStatement pstm = conn.prepareStatement(sql); 
	//param 1
	pstm.setString(1, a.getAcao()); 
	//param 2
	pstm.setInt(2, a.getFuncionario().getId()); 
	pstm.execute(); 
	this.desconectar(); 
}

Fiz do jeito que você instruiu…Mas ele ainda não quer mandar pra tabela Auditoria, não sei o por que :frowning:

Ele inseriu normal, mas é como se tivesse ignorado essa tabela…

Vou mandar o switch todo desta parte…

`` switch (op) {

     case "inserir":
     a.setAcao(("Inseriu o Plano:"+p.getNome()));            
     Funcionario f = (Funcionario) 
    session.getAttribute("funcionario"); `Essa parte é pegando a sessão do funcionario logado`
     a.setFuncionario(f);
      p.inserir();
        break;
       case "alterar":
     p.alterar();    
         break;
         case "excluir":
            p.excluir();
         break;
            }
            response.sendRedirect("plano_de_pagamento.jsp");

Creio que falta vc passar o objeto por parametro nesse metodo. Uma forma de vc saber qual é o erro e lançar a exceção na hora da execução do método. Assim, fica mais fácil de saber se tem algum problema e onde ele está.

Vc lança a exception? Se não, faça seu método lançar e coloque o trace aqui para a comunidade poder analisar.

Olhando só o que vc passou, o que percebi é que o objeto acao não está sendo passado para o método.

1 curtida

Por via das dúvidas, vou lhe passar todo o cod ta GerenciarPlano

package control;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import model.Auditoria;
import model.Funcionario;
import model.Plano;

public class GerenciarPlano extends HttpServlet {

/**
 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
 * methods.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {
        /* TODO output your page here. You may use following sample code. */
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet GerenciarPlano</title>");            
        out.println("</head>");
        out.println("<body>");
        try {
            HttpSession session = request.getSession(); 
            Plano p = new Plano();
            Auditoria a = new Auditoria();  
            String op = request.getParameter("op");     
            String nome = request.getParameter("nome");
            String preco = request.getParameter("preco"); 
            String descricao = request.getParameter("descricao");
            String funcionario_id = request.getParameter("funcionario_id");
      
            String id = request.getParameter("id");
            
            
            out.print(nome+""+descricao+""+preco+""+funcionario_id+"");
            
            if (op.equals("inserir") || op.equals("alterar")) {
                if (nome.isEmpty() || nome.equals("")) {
                    out.print("Favor preencher o campo NOME!");
               } else if (preco.isEmpty() || preco.equals("")){
                    out.print("Favor preencher o campo PRECO");
                } else if (descricao.isEmpty() || descricao.equals("")){
                    out.print("Favor preencher o campo DESCRICAO!");
                } else if(funcionario_id.isEmpty() || funcionario_id.equals("")){
                    out.print("Favor colocar um funcionario");
                
                } else {        
                    p.setNome(nome);
                    p.setPreco(Double.parseDouble(preco));
                    p.setDescricao(descricao);
                    Funcionario f = new Funcionario();
                    f.setId(Integer.parseInt(funcionario_id));
                    p.setFuncionario(f);  
                   
                }
            }
            if (op.equals("excluir") || op.equals("alterar")) {
                if (id.isEmpty() || id.equals("")) {
                    out.print("Favor informar o ID!");
                } else {
                    p.setId(Integer.parseInt(id));
                }
            }

            switch (op) {
                case "inserir":
                 a.setAcao(("Inseriu o Plano:"+p.getNome()));   
                 Funcionario f = (Funcionario)
                 session.getAttribute("funcionario");
                 a.setFuncionario(f);
                  p.inserir();
                    break;
                case "alterar":
                 p.alterar();    
                    break;
                case "excluir":
                    p.excluir();
                    break;
            }
            response.sendRedirect("plano_de_pagamento.jsp");
        } catch (Exception e) {
            out.print("Erro: " + e);
        }
        out.println("</body>");
        out.println("</html>");
    }
}

esse p.inserir(); é do Plano, que foi instanciado no inicio da pagina

Aqui a tabela de Auditoria a Model.

package model;
import java.util.ArrayList;

public class Auditoria {
private int id;
private String acao;
private String data_hora;
private Funcionario funcionario;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getAcao() {
    return acao;
}

public void setAcao(String acao) {
    this.acao = acao;
}

public String getData_hora() {
    return data_hora;
}

public void setData_hora(String data_hora) {
    this.data_hora = data_hora;
}


public Funcionario getFuncionario() {
    return funcionario;
}

public void setFuncionario(Funcionario funcionario) {
    this.funcionario = funcionario;
}

  public void inserir() throws Exception{
    AuditoriaDAO aDAO = new AuditoriaDAO();
    aDAO.inserir(this); 
}
   public ArrayList<Auditoria> listar() throws Exception{
    AuditoriaDAO aDAO = new AuditoriaDAO();
    return aDAO.listar();
}
public void carregar() throws Exception{
    AuditoriaDAO aDAO = new AuditoriaDAO();
    this.acao = aDAO.carregarPorId(this.id).getAcao();
    this.data_hora = aDAO.carregarPorId(this.id).getData_hora();
    this.funcionario = aDAO.carregarPorId(this.id).getFuncionario();
}

}

Está faltando vc chamar esse metodo junto com o p.inserir().

De:

Para:

Mas, tenta jogar a Exception, pra ver se sai algum trace por lá.

deu esse erro aqui.
Erro: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘now(), funcionario_id) VALUES(‘Inseriu o Plano:Semestral’,4)’ at line 1

No inicio do erro veio os campos que eu digitei : “Semestral” Plano com duracaoo de 6 meses"250.0" “4”

Cara, me perdoe, eu me enganei…rsrs

O SQL não está bom. Erro primário meu…faça assim:

INSERT INTO auditoria (acao, seu_campo_data, funcionario_id) VALUES(?, ?, ?)

E nos question marks, coloque 3 assim:

	//param 1
	pstm.setString(1, a.getAcao()); 
	//param 2
	pstm.setString(2, "now()");//veja a doc do MySQL pra saber qual é a melhor função pra vc
	//param 3
	pstm.setInt(3, a.getFuncionario().getId());

Isso deve resolver

Deu isso aqui…

AnualDuracao de 1 ano500.04Erro: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: ‘now()’ for column ‘data_hora’ at row 1

Isso ai seria por que no meu banco de dados o campo data_hora está como datetime ?