[JavaMail|Commons] - Mistérios de envio

9 respostas
Java_Boy

Olá pessoal,

eu sei que o tema sobre envios de email já foi abordado aqui, mas não achei ninguém com um problema similar ao meu então vou compartilhá-lo aqui:

Situação -> Usar API´s JavaMail e CommonsMail para enviar um email com imagem em anexo (logo de algo)

Problema 1 -> Quando testo no ambiente windows, com o Microsoft ESMTP MAIL Service funciona que é uma beleza, tanto com Commons como com o padrão do JavaMail, imprimindo no fim a mensagem de sucesso

250 2.6.0 Queued mail for delivery
QUIT

Problema 2 -> Quando passo para um ambiente linux, com o ESMTP Postfix, tudo ocorre perfeitamente nos logs

250 Ok: queued as B2A12952B
QUIT
221 Bye

mas o email simplesmente não chega, e caso eu faça o mesmo com um texto puro o email chega, ou seja,a imagem influencia, mas não sei se é por causa do PostFix ou das API´s de email.

Espero ter conseguido explicar bem.

Conseguem imaginar algo que posso estar ocorrendo?

[]s

9 Respostas

P

Bom dia A.L,

Meu primeiro post aqui depois de quase 2 anos de sangue-suga de informações (rsss) resolvi me cadastrar no GUJ e não poderia deixar de tentar ajudar alguém nesse primeiro post.

Bom A.L, pelo que entendi, você está utilizando a API JavaMail e não está conseguindo enviar mensagens do tipo multipart/mixed contendo anexos é isso?

Caso positivo, seria interessante você ativar o modo debug da session atraves do comando: setDebug(true) e postar toda a negociação. Normalmente o content-type da parte do anexo não é identificada atraves da extensão do arquivo passado.

Possível solução:
Quando incluo anexos aos e-mails que envio, eu costumo utilizar o setDataHandler e não o attachFile, pois nele eu posso setar manualmente o tipo do arquivo. A vantagem do attachFile é que você apenas seta o caminho do arquivo e pronto. Na verdade é oque ele faz a leitura do arquivo como vc faria com o setDataHandler do mesmo jeito.

Hierarquia de mensagens do JavaMail:
É interessante você dar uma olhadinha na hierarquia de construção de mensagens do JavaMail. Apesar de que o JavaMail possuir isso internamente, é bom saber como utilizar os objetos de modo correto. Mas nada que a gente possa resolver aqui caso você tenha duvida sobre alguma coisa.

Vlw.

Java_Boy

Olá petruki! Vlw pelo tempo para responder meu problema, então

ativei o debug sim, segue a negociação, sou leigo nessa parte mas parece estar tudo certo :

******************************************************************

==**==ENVIANDO EMAIL...
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 25, isSSL false
220 columbo-d.cjf.local ESMTP Postfix
DEBUG SMTP: connected to host "localhost", port: 25

EHLO columbo-d
250-columbo-d.cjf.local
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "10240000"
DEBUG SMTP: Found extension "VRFY", arg ""
DEBUG SMTP: Found extension "ETRN", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<[email removido]>
250 Ok
RCPT TO:<[email removido]>
250 Ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP: [email removido]
DATA
354 End data with .
From: [email removido]
To: [email removido]
Message-ID: <3375301.17.1224499800279.JavaMail.tomcat@columbo-d>
Subject: HTML mail with images
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="----=_Part_16_6484689.1224499800277"

------=_Part_16_6484689.1224499800277
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

Texto teste

------=_Part_14_20978358.1224499680353 Content-Type: image/png Content-Transfer-Encoding: base64 Content-ID:

iVBORw0KGgoAAAANSUhEUgAAANIAAABeCAYAAABW60rhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz
AAALEgAACxIB0t1+/AAAAB90RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgOLVo0ngA
ABhWcHJWV3ic7VsJVFzXeX4zI8O8yYxiPKOCTR0PBhvbI8mxRj2nPSdJU7sncVq3TU6OkyY5bnoc
h9puYjvxksiLbDnWvtiy0MIiNiFAC2LfEULskkAgkNgRuxCLEPsuvv7/ffOGQV6kE+k47ake3Jm3
------=_Part_14_20978358.1224499680353--
.
250 Ok: queued as 591516E7
QUIT
221 Bye
**==EMAIL ENVIADO

******************************************************************

Para montar a imagem estou usando esse setDataHandler mesmo, mas notei que estou usando multipart/related ao invés de mixed como voce disse

BodyPart messageBodyPart = new MimeBodyPart();
        DataSource fds = new FileDataSource(file);
        messageBodyPart.setDataHandler(new DataHandler(fds));
        messageBodyPart.setHeader("Content-ID","<image>");

Já pensei também se pode ser a extensão da imagem(.png).

Oque acha disso tudo?

[]s e vlw novamente

P

Ótimo,
Nesse caso a imagem não é um anexo, mas sim parte de uma parte, ou seja, ela está sendo referenciada por outra parte atraves do campo Content-ID. Até aí está tudo OK!

Definição da multipart/related:
Mensagem agregada por outras partes. Muito comum nesse seu caso onde há apenas um conteúdo HTML (geralmente é a primeira parte) e referencias dentro dela de outras partes (utilizando o Content-ID)

Se tiver curiosidade sobre outros tipos de mensagems: http://en.wikipedia.org/wiki/MIME

Bom, vamos ao que interessa.
Se problema existir, ele poderá estar na parte do cabeçalho da parte da imagem:
------=_Part_14_20978358.1224499680353
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-ID:

Comumente utiza-se a sintaxe a seguir para esse tipo de parte:
------=_Part_14_20978358.1224499680353
Content-Type: image/png; name=“image.png”
Content-Transfer-Encoding: base64
Content-ID:

Agora não sei se a omissão do campo name deve ter causado a não identificação dessa parte.
No caso da extensão do arquivo acho dificil a possibilidade de que o cliente não interprete ou bloqueie o arquivo.

Outro detalhe importante:
Observe que existe um código para identificar as partes, por exemplo: ------=_Part_14_20978358.1224499680353
O codigo da parte da mensagem no caso de um e-mail do tipo multipart/related deve ser o mesmo do cabeçalho do e-mail (onde tem o Subject, From, To, etc.)
No seu caso o código da parte que contém a imagem deveria ser: ----=_Part_16_6484689.1224499800277 e não: Part_14_20978358.1224499680353
Verifique isso!

Desculpe pela falta de organização do post (rss) é que eu acabei escrevendo e lembrando de detalhes depois de ter escrito boa parte dele (uaauhahauhh)

Vlw,

P

Aproveitando, vou te mostrar um exemplo que eu gerei aqui no serviço de SMTP que eu desenvolvi pra empresa onde trabalho.
Observe em negrito o que é importante.

Date: Mon, 20 Oct 2008 13:17:17 -0300 (GMT-03:00)

From: <a>"[email removido]</a>" <a href="mailto:[email removido]">[email removido]</a>

To: [email removido]

Message-ID: <a href="mailto:13238549.5.1224519442203.JavaMail.Rogerio@est02">13238549.5.1224519442203.JavaMail.Rogerio@est02</a>

Subject: Teste de e-mail

MIME-Version: 1.0

Content-Type: multipart/related;

boundary="----=_Part_3_4909906.1224519437984"

------=_Part_3_4909906.1224519437984
Content-Type: multipart/alternative;
boundary="----=_Part_4_10446619.1224519437984"

------=_Part_4_10446619.1224519437984
Content-Type: text/html; charset=Cp1252
Content-Transfer-Encoding: quoted-printable

Conteúdo HTML Aqui

------=_Part_4_10446619.1224519437984–

------=_Part_3_4909906.1224519437984
Content-Type: image/jpeg;
name=“5C1.jpg”
Content-Transfer-Encoding: base64
Content-ID: 9D0560717D244A4D9FD28C9AF4F3C3F2@est02

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e
Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCADXALcDASIA
…(RESUMI AQUI)
------=_Part_3_4909906.1224519437984–
.
250 2.0.0 OK [telefone removido] h38sm9599510wxd.29

Resumindo o que ocorre.
A mensagem root: Part_3_4909906.1224519437984
Contém as partes: Parte agregadora do tipo multipart/alternative que referencia a parte do conteúdo do tipo text/html
Contém a parte relacionada: Parte do tipo image/jpeg

Desenhando fica algo mais ou menos assim:

ROOT PART (related)
|- MULTIPART/ALTERNATIVE
|----------| TEXT/HTML
|----------| Aqui pode haver um TEXT/PLAIN
|
|- IMAGE/JPEG

Java_Boy

petruki , muito boa explicação

realmente o codigo de parte que mandei era de outra mensagem, na realidade estão correto. Estou pensando aqui, essa parte de mime, “related”, “alternative” e “mixed” pode influenciar, ou até mesmo o tipo de imagem, que no meu caso é png?

E no caso no meu nao aparece essa propriedade name que voce disse. Seu servidor de smtp roda no linux ou windows?

Gerei novamente um log

==**==ENVIANDO EMAIL…
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host “localhost”, port 25, isSSL false
220 columbo-d.cjf.local ESMTP Postfix
DEBUG SMTP: connected to host “localhost”, port: 25

EHLO columbo-d
250-columbo-d.cjf.local
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250 8BITMIME
DEBUG SMTP: Found extension “PIPELINING”, arg “”
DEBUG SMTP: Found extension “SIZE”, arg “10240000”
DEBUG SMTP: Found extension “VRFY”, arg “”
DEBUG SMTP: Found extension “ETRN”, arg “”
DEBUG SMTP: Found extension “8BITMIME”, arg “”
DEBUG SMTP: use8bit false
MAIL FROM:[email removido]
250 Ok
RCPT TO:[email removido]
250 Ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP: [email removido]
DATA
354 End data with .
From: [email removido]
To: [email removido]
Message-ID: 8550088.13.1224521400400.JavaMail.tomcat@columbo-d
Subject: HTML mail with images
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_12_13935769.1224521400399"

------=_Part_12_13935769.1224521400399
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

TESTE

------=_Part_12_13935769.1224521400399 Content-Type: image/png Content-Transfer-Encoding: base64 Content-ID:

iVBORw0KGgoAAAANSUhEUgAAAAEAAAAFCAIAAAAL5hHIAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAA9JREFU
GFdj+P//PwMaBgCVfg7yjjav9gAAAABJRU5ErkJggg==
------=_Part_12_13935769.1224521400399–
.
250 Ok: queued as 644401302B
QUIT
221 Bye
**==EMAIL ENVIADO

P

O serviço roda em ambas as plataformas. Só tive que ter duas versões do Java Service Wrapper, uma pra windows e outra pra linux.

Então, no caso de mensagens multipart/mixed elas são utilizadas para enviar mensagens que contém diferentes tipos de partes, incluindo a altertative, related. Na maioria dos casos utiliza-se esse tipo de parte para anexar arquivos. Importante dizer também que nesse caso nunca deve ser atrelado o conteúdo da mensagem diretamente a mensagem (mixed).

Cara, vo te dizer, demorei pra saca como tudo isso funciona. Mas é o seguinte. Vo coloca alguns exemplos de alguns casos pra ver se de maneira programática vc consegue visualizar melhor:

Situação: Mensagem com conteúdo html e imagem dentro dela

MimeMultipart root; // Nela serão armazenadas todas as partes
MimeMultipart under_root = new MimeMultipart("multipart/related"); // Aqui conterá o conteúdo que pode ser lido (quoted-printable)

/* Vc não pode simplesmente adicionar uma MimeMultipart dentro de outra. Vc deve criar um bodypart e adicionar como seu conteudo a Multipart que no caso é a related */
MimeBodyPart body_root = new MimeBodyPart();
body_root.setContent(under_root);
root.addBodyPart(body_root); //Adicione a bodypart dentro da mensagem principal

//Montada a estrutura, é só adicionar os bodyparts nos lugares corretos:
MimeBodyPart body = new MimeBodyPart();
body.setDataHandler(CONTEUDO HTML AQUI);
under_root.addBodyPart(body);

body = new MimeBodyPart();
body.setDataHandler(CONTEUDO DA SUA IMAGEM AQUI);
root.addBodyPart(body); // Aqui que está o segredo (Adiciona essa parte no corpo da mensagem principal)

Para mensagens com anexo é a mesma coisa, só muda o tipo para multipart/mixed e no cabeçalho do anexo que no caso é uma imagem terá um novo header Content-Disposition: attachment

Java_Boy

Hmm entendi! Estou vendo que muita coisa do header não está vindo para o postfix do linux, vou tentar setar na mão.

Por hora muito obrigado pela ajuda hein petruzi, acho que agora falta muito pouco para dar certo. Espero que tenha ajudado mais alguém que leu essa thread.

Vlwsss de novo!Qualquer coisa retorno aqui, vou testar com isso que você disse.

Flwss,[]s!

Java_Boy

Desenterrando o tópico!

Muito obrigado pela ajuda petruki! Esse serviço já está rodando no sistema em produção e fará aniversario de 1 ano rsrs

O problema!? A maldita VPN dos ambientes de desenvolvimento e mais ainda, as regras de envio do servidor de email: Só válidas para emails com domínio @xxx.yy.br.

Espero que esse poste ajude quem esteja com problemas similares no envio de emails com o serviço do Java.

[]s!

P

Opa, bom saber A.L.
Parabéns e sucesso.

Abraço

Criado 20 de outubro de 2008
Ultima resposta 22 de out. de 2009
Respostas 9
Participantes 2