JavaMail - anexar arquivo em email

Boa tarde, antes que me digam que ja existe um tópico sobre isso eu vi o tópico, porém a implementação que quero é um pouco diferente.

Este é o tópico que mostra como fazer o anexo:

Porém no meu caso eu gostaria de passar um arquivo que vem do banco.
Fiz a implementação como o pessoal do tópico disse porém ele não encontra o arquivo,
pelo que entendi ele busca esse arquivo em um endereço por exemplo C:\pasta\anexo.txt

No meu caso ele vem do banco, uma imagem.

segue trecho do código:

MimeBodyPart image = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
if(filename != null){

                    // EXISTE UM MÉTODO createImgTag(id) QUE TRAZ A IMAGEM DO BANCO.
  		DataSource source = new FileDataSource(createImgTag(id));
  		image.setDataHandler(new DataHandler(source));
  		image.setFileName(title);
  		content.addBodyPart(image);
  		
  	    BodyPart mbp = new MimeBodyPart();
          mbp.setDataHandler(new DataHandler(source));
          mbp.setDisposition(Part.ATTACHMENT);
          multipart.addBodyPart(mbp);
  	}
  
  }
  msg.setContent(content);
  // send the message
  Transport.send(msg);

Após feito isso é lançada uma exception dizendo que não encontrou o arquivo.

Alguém sabe me dizer pq?

Obrigado!

Opa tudo bem? Eu tbm tive dificuldades em gerar um email com arquivos do tipo byte[], ja q recuperava dentro do banco. Consegui resolve-lo com a seguinte classe:

public class EnviarEmail extends ThreadCommand {

public EnviarEmail(JProgressBar progress) {
    super(progress);
}
private List<Contato> to;
private String subject;
private String message;
private List<Anexo> anexos;

public void sendMail(List<Contato> to, String subject, String message, List<Anexo> anexos) {
    this.to = to;
    this.message = message;
    this.subject = subject;
    this.anexos = anexos;
}

@Override
public void execute() {
    Properties props = new Properties();
    props.put("mail.transport.protocol", "smtp"); //define protocolo de envio como SMTP
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", "smtp.gmail.com"); //server SMTP do GMAIL
    props.put("mail.smtp.auth", "true"); //ativa autenticacao
    props.put("mail.smtp.user", "******"); //usuario ou seja, a conta que esta enviando o email (tem que ser do GMAIL)
    props.put("mail.debug", "false");
    props.put("mail.smtp.port", "465"); //porta
    props.put("mail.smtp.socketFactory.port", "465"); //mesma porta para o socket, padrão do Gmail
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.socketFactory.fallback", "false");
    Session session = Session.getInstance(props, new javax.mail.Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("**********@gmail.com", "******");
        }
    });
    //  session.setDebug(true); //Habilita o LOG das ações executadas durante o envio do email
    Message msg = new MimeMessage(session);
    try {
        msg.setFrom(new InternetAddress("*******@gmail.com"));
        msg.setSubject(subject);
        Multipart mp = new MimeMultipart();
        MimeBodyPart mbp1 = new MimeBodyPart();
        mbp1.setText(message); // adiciona a mensagem 
        mp.addBodyPart(mbp1);
        if (anexos.size() > 0) { // verifica se possui anexos
            for (Anexo anexo : anexos) { // este for adiciona ao mp todos os anexos listados
                mbp1 = new MimeBodyPart(); // reconstroi o MimeBody para que possa ser usado na implementção dos anexos
                mbp1.setDisposition(Part.ATTACHMENT);
                mbp1.setDataHandler(new DataHandler(new ByteArrayDataSource(anexo.getImagem(), getMimeType(anexo.getImagem()))));
                mbp1.setFileName(anexo.getNomeAnexo());
                mp.addBodyPart(mbp1); // adiciona ao Mp o anexo convertido
            }
        }
        msg.setContent(mp); // adiciona a mensagem todo o mp gerado pelo texto + anexo
        for (Contato to1 : to) { // pega lista de contatos 
            progress.setValue(80);
            progress.setString("Enviando para " + to1.getEmail()); // define o jprogressbar da janela de enviarEmail_i
            msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to1.getEmail())); // define destinatario
            msg.saveChanges(); // salva a mensagem - importante ser depois de definir destinatario
            Transport.send(msg); // envia mensagem - Isso demora bastante
            progress.setString("Enviado com Sucesso!!");
            progress.setValue(100);
        }
    } catch (MessagingException | HeadlessException e) { // caso ocorra erro no envio ou criação de mensagem
        progress.setValue(0);
        System.out.println(">> Erro: Envio Mensagem " + e.getMessage());
    }
}

private String getMimeType(byte[] file) { // este método verifica e possibilita diversos tipos de arquivos como .doc ou .xls
    try {
        MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
        eu.medsea.mimeutil.MimeType m = MimeUtil.getMostSpecificMimeType(MimeUtil.getMimeTypes(file));
        MimeUtil.unregisterMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
        return m.toString();
    } catch (OutOfMemoryError a) {
        System.out.println(a.getMessage());
        return "";
    }
}

Dê detalhes para o:

for (Anexo anexo : anexos) { // este for adiciona ao mp todos os anexos listados
            mbp1 = new MimeBodyPart(); // reconstroi o MimeBody para que possa ser usado na implementção dos anexos
            mbp1.setDisposition(Part.ATTACHMENT);
            mbp1.setDataHandler(new DataHandler(new ByteArrayDataSource(anexo.getImagem(), getMimeType(anexo.getImagem()))));
            mbp1.setFileName(anexo.getNomeAnexo());
            mp.addBodyPart(mbp1); // adiciona ao Mp o anexo convertido
        }
  • O anexo.getImagem() recebe byte[];

  • O getMimeType() permite enviar documentos mais complexos como Xsl, Zips e etc.

  • Ignore o progress Isso n passava de um JProgressbar que indicava o carregamento…

  • O looping no envio, é pq minha classe enviava para mais de um contato.

  • Este comando converte a porra toda:

    mbp1.setDataHandler(new DataHandler(new ByteArrayDataSource(aquivoAqui, eAquiTbm))));

Boa tarde 4mega, primeiro obrigado pela resposta, alguns ajustes na sua solução pra minha aplicação e funcionou!

Ficou assim:

public void sendWithImage(Long id) throws Exception {
Properties emailProperties = new Properties();
Session session = null;

  if (recipients == null || recipients.isEmpty()) {
  	throw new Exception(Util.getML(MlGeneralItem.MAIL_MESSAGE_WITHOUT_RECIPIENTS, user));
  }
  if (subject == null) {
  	throw new Exception(Util.getML(MlGeneralItem.MAIL_MESSAGE_WITHOUT_SUBJECT, user));
  }
  emailProperties.put("mail.smtp.username", username);
  emailProperties.put("mail.smtp.password", password);
  emailProperties.put("mail.smtp.host", host);
  session = Session.getDefaultInstance(emailProperties, null);
  Message msg = new MimeMessage(session);
  msg.setFrom(new InternetAddress(userFrom));
  msg.addRecipients(Message.RecipientType.TO, getAdresses());
  msg.setSubject(subject);
  Multipart content = new MimeMultipart();
  MimeBodyPart textPart = new MimeBodyPart();
  textPart.setHeader("Content-Type", this.contentType);
  textPart.setHeader("Charset", this.charset);
  textPart.setContent(this.textMsg, this.contentType);
  content.addBodyPart(textPart);
  for (EmailImage emailImage : images) {
  	content.addBodyPart(getEmbeddedImage(emailImage));
  }
  MimeBodyPart messageBodyPart = new MimeBodyPart();
  String filename = fileWay;
  if (filename != null) {
  	DataSource source = new FileDataSource(filename);
  	messageBodyPart.setDataHandler(new DataHandler(source));
  	messageBodyPart.setFileName(title);
  	content.addBodyPart(messageBodyPart);
  }
  if (createImgTag(id) != null) {
  	MimeBodyPart image = new MimeBodyPart();
  	Multipart multipart = new MimeMultipart();
  	if (filename != null) {
  		DataSource source = new FileDataSource(createImgTag(id));
  		image.setDataHandler(new DataHandler(new ByteArrayDataSource(getByteImage(id), source.getContentType())));
  		image.setFileName(getNameFile(id));
  		content.addBodyPart(image);
  		BodyPart mbp = new MimeBodyPart();
  		mbp.setDataHandler(new DataHandler(source));
  		mbp.setDisposition(Part.ATTACHMENT);
  		multipart.addBodyPart(mbp);
  	}
  }
  msg.setContent(content);
  // send the message
  Transport.send(msg);

}

Neste caso estou fazendo anexo de dois arquivos, um que fica em uma pasta temporária e outro que fica em no banco!

Obrigado pela ajuda!