sexta-feira, 12 de setembro de 2014

Enviar E-mail com texto e anexo Commons Mail

Olá, recentemente comecei testar novas tecnologias para envio de e-mails. Onde muito se falava do Commons Mail, por ser simples e de fácil configuração se considerado com o Java Mail, o qual é mais complexo. 

Curiosidade importante, Commons Mail é baseado no Java Mail. Bom vamos la para utilizar o Commons Mail é necessário o Java Mail e o próprio Commons Mail, e caso esteja utilizando Java 6 é necessario o JAF.

No próprio site da Commons Apache, existe diversos tutorias básicos contendo ótimos exemplos confira aqui.

No meu caso vou dar uma importante dica, caso como eu você esteja utilizando iReport para gerar relatórios ou algum outro meio que utilize Array de Bytes(Essa solução é usada para  que não seja necessário persistir o arquivo em disco). Se parou para olhar o exemplo no site da Commons Apache percebeu que ele usa a classe EmailAttachment  , e esta classe apenas aceita o caminho do arquivo (Em String) que ja esta no disco. E como ja dito para casos que você vai gerar o arquivo em por exemplo um Array de Bytes existe métodos especifico dentro da classe MultiPartEmail.  O método sobrecarregado chamado attach, possui atualmente cerca de 6 metodos com este mesmo nome utilizando construtores diferentes( Isso é mesmo necessario ser dito ? ). O construtor que irei demostrar no codigo a baixo é o seguinte:


public MultiPartEmail attach(DataSource ds,String name,String description,String disposition) throws EmailException

Este construtor recebe um Objeto do tipo DataSource contendo os dados do mesmo, um nome, uma descrição e disposição. Para resumir abaixo o codigo que utilizo hoje a partir deles com certeza voce vai entender muito melhor:


public class Email {  
    private Object[] para;
    MultiPartEmail multiPartEmail;

    public Email() {
        multiPartEmail = new MultiPartEmail();      
        try {
            multiPartEmail.setFrom("seuMail@seuDominio","Seu Nome");
        } catch (EmailException ex) {
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, ex);
        }
        multiPartEmail.setAuthentication("emailAutencar@dominio", "senha");
        multiPartEmail.setHostName("seuHost");
        multiPartEmail.setSmtpPort(PORTA_SMTP);
        multiPartEmail.setDebug(true);//DEBUG
    }

    @Override
    public boolean enviar() {
        try {
            for (Object object : para) {//Percorre a lista de destinatarios e add ao email
                multiPartEmail.addTo(object.toString());
            }
            multiPartEmail.send();//envia
            return true;
        } catch (EmailException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Informação do Sistema", JOptionPane.ERROR_MESSAGE);
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    @Override
    public boolean enviar(byte[] arquivo) {
        try {
            multiPartEmail.attach(new ByteArrayDataSource(arquivo, "aplication/pdf"), //Converte Array de Bytes em um DataSource
                                  new SimpleDateFormat("yyyyMMdd HH:mm").format(new Date()) + ".pdf",//Nome do Arquivo escolhi que seria desta Forma
                                  "relatorio",
                                  EmailAttachment.ATTACHMENT);
        } catch (EmailException ex) {
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, ex);
        }
        return this.enviar();
    }

    @Override
    public void setPara(List<String> para) {
        this.para = para.toArray();
    }
   
    @Override
    public void setMensagem(String mensagem) {
        try {
            multiPartEmail.setMsg(mensagem);//Este Metodo deve ser chamado antes do anexo, caso contrario o texto nao será exibido
        } catch (EmailException ex) {
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void setAssunto(String assunto) {
        multiPartEmail.setSubject(assunto);
    }

}

obs: Eu levei um tempo para descobrir um pequeno "Pulo do Gato", apesar de estar descrito da Documentação oficial, quando desejar enviar email com mensagem é necessario que no caso MultiPartEmail, o metodo referente ao corpo do email seja chamado antes ao metodo referente ao anexo, caso contrario  não irá funcionar como esperado.