Problema com auditoria[RESOLVIDO]

36 respostas
I

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

E

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.

J

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.

I

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

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

I

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

}
I

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

E

Bom dia Isaias_Barbosa,

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

I

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?

E

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

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

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.

I

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

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

I

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

}

E

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

I

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

I

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

E

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

I

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 ?

I

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 ?

I

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

E

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

I

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

E

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.

I

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

E
pstm.setString(2, "SYSDATE()");
I

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

I

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…

E

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.

I

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

E

Desculpe,setTimestamp(2, date);

E

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

I

Agora sim, cara muito obrigado, muito Obrigado mesmo…

I

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.

E

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

I

Obrigado

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