使用javax.mail发送邮件,并在邮件中嵌入图片

背景:工作中有一个场景需要在邮件中插入图片,而又没有邮件图片服务器,所以需要考虑在邮件的内容中嵌入图片。邮件的正文中有很多表格,所以使用html写入正文。

实现方法以及遇到的问题:

  1. HTML5 的 canvas 元素使用JavaScript绘图
    在实际尝试中发现邮件客户端支持html5,但是禁用了js,所以此方法不可行。

  2. 在附件中放入图片
    此方法的结果是图片只能位于邮件的末尾,而且不同的邮件客户端显示效果不同,例如Apple mail会直接把图片显示出来(文本附件不会直接显示),而163 mac客户端会显示一个图片的缩略图,需要下载才能查看,在163的iPhone客户端则是直接以附件形式存在。

  3. 将jpg格式的图片使用base64编码,然后插入到html的image标签中
    "<img src=\"data:image/jpeg;base64, "+ file_base64_code +"\" /> "
    这种方法可以将图片显示在html的任意位置,在Apple mail和163 mac客户端都可以正常显示,而在163的iPhone客户端中图片不能正常显示,原因未知。

  4. 在邮件的附件中放入图片,并在html格式的正文中以cid的方式引用
    方法1和2用的封装过的邮件接口,在此方法中用的是java邮件jar包javax.mail,需要使用MimeMessageMimeMultipartMimeBodyPart等几个类来构造邮件的标题和内容,用法可以参考Java发送邮件,其中MimeMessage代表一封邮件,邮件中包含的MimeMultipart,需要为其指定类型,可以在构造函数中指定,也可以使用setSubType方法指定,常用的类型有related、mixed、alternative这三种,其在内容中的格式为:
    在这里插入图片描述
    除了这三种还有其他类型,这里涉及到一个parallel类型,后面会说明。
    在向MimeBodyPart中添加内容时可以指定内容的类型,类型的内容可以参考:MIME类型Content-type,也可以不指定,系统会自动匹配一个类型。

    实际开发中遇到了以下几个问题:
    1、不同邮件客户端对MimeBodyPart的支持并不相同,并不一定会按照设计好的方式进行显示,需要实际测试后才可以
    2、由于apple mail会直接显示附件图片(把Content-type设置为inlineattachment均无效),所以除了在引用未知会显示图片意外,附件部分也会把图拍直接显示出来,导致同一个图片在邮件中会出现两次。在163 mac 客户端显示正常,而在163的iPhone客户端则会把包含图片的html内容和图拍都以附件的形式存在。。。
    3、对于在同一个MimeMultipart中同时存在两个MimeBodyPart的情况,若MimeMultipart的格式设置为alternative,则在apple mail中只会显示一个MimeBodyPart,需要将MimeMultipart的type设置为parallel,两个MimeBodyPart才可以正常显示,而这两种type在163 mac客户端则可以正常显示,问题的原因未知。

结论:
考虑到上面遇到的诸多问题,最终考虑使用方法3和方法4结合的方式,这样可以避免在图片在附件中的重复出现,而且可以任意指定图片出现的位置。
在开发中可以将session的debug模式打开,这样可以更加直观的看到邮件各个部分的构成,便于开发调试,session.setDebug(true),在Apple mail中也可以使用显示->邮件->源代码的方式查看邮件的源码。

问题:
1、发送、抄送或者密送邮件给多个人需要参考:一次发送邮件给多人

发布了16 篇原创文章 · 获赞 0 · 访问量 804

猜你喜欢

转载自blog.csdn.net/shengruxiahua2571/article/details/103293981