Problema com auditoria[RESOLVIDO]

36 respostas
Isaias_Barbosa

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 ?

36 Respostas

Emerzoom

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.

javaflex

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.

Isaias_Barbosa

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;
Isaias_Barbosa

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

Isaias_Barbosa

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();

}
Isaias_Barbosa

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

Emerzoom

Bom dia Isaias_Barbosa,

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

Isaias_Barbosa

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?

Emerzoom

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(); 
}
Isaias_Barbosa

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");
Emerzoom

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.

Isaias_Barbosa

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>");
    }
}
Isaias_Barbosa

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

Isaias_Barbosa

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();
}

}

Emerzoom

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á.

Isaias_Barbosa

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

Isaias_Barbosa

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

Emerzoom

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

Isaias_Barbosa

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 ?

Isaias_Barbosa

Cara, quase conseguir resolver aqui, eu coloquei como String o data_hora no banco, ai deu certo…Mas quando eu vou na auditoria aqui, ele não me passa a hora, ele mostra apenas o campo now()…tentei então mudar pro datetime…e na tabela auditoria colocar o data_hora para DATE…mas ai ele da o erro de cima…no caso então…tem alguma solução ?

Isaias_Barbosa

E quando eu inserir aqui com o campo datetime…qnd vou na tela auditoria ele me da isso Erro: java.sql.SQLException: Value ‘0000-00-00 00:00:00’ can not be represented as java.sql.Date

Emerzoom

Sim. Pra isso, vc precisa então, no parametro 2, colocar a função correspondente ao valor esperado.
Passa como SYSDATE()
Veja a doc:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sysdate

Isaias_Barbosa

Só mais uma coisa…na tabela de auditoria tem problema eu deixar como String data_hora ?..

Emerzoom

Não tem. Isso fica ao seu gosto. Outra coisa que vc pode tentar para o parametro 2 é:

//param 2
	pstm.setString(2, new Timestamp(new Date().getTime()));

São várias as possibilidades.

Isaias_Barbosa

você pode me falar como ficaria na funcao de Sysdate ?

Emerzoom
pstm.setString(2, "SYSDATE()");
Isaias_Barbosa

Desculpa está pedindo tudo assim, é por que tenho que apresentar isso ainda hoje…Mas eu vou da uma estudada nisso mais afundo, depois…

Isaias_Barbosa

Se eu colocar no banco de dados o campo data_hora como datetime, ele da o erro ali em cima…se caso eu deixar como VARCHAR ai ele me da esse nome ai…

Emerzoom

Coloca a coluna como TIMESTAMP, dps, coloca isso:

java.sql.Timestamp date = new java.sql.Timestamp(new java.util.Date().getTime());
pstm.setString(2, date);

Não tem como errar.

Isaias_Barbosa

nesse caso ai, eu vou ter que passar de String para Date certo ?:

Emerzoom

Desculpe,setTimestamp(2, date);

Emerzoom

Segue um post que pode ajudar:
https://www.mkyong.com/jdbc/how-to-insert-timestamp-value-in-preparedstatement/

Isaias_Barbosa

Agora sim, cara muito obrigado, muito Obrigado mesmo…

Isaias_Barbosa

Vou dar uma estudada mais a fundo nisso depois para entender melhor…Mas por hoje, você me salvou, vlws mesmo…Pode Fechar o tópico.

Emerzoom

Que beleza!
[RESOLVIDO] e sucesso no seu trabalho!

Isaias_Barbosa

Obrigado

Criado 28 de novembro de 2017
Ultima resposta 29 de nov. de 2017
Respostas 36
Participantes 3