浅析JavaMail发送邮件后再通过JavaMail接收格式问题
复杂邮件发送问题
关于 javamail 如何发送邮件这里就不赘述了,网上有很多例子。其中最复杂的邮件发送莫过于 html邮件包含内嵌图片以及附件,最近项目中的这项功能我在发送邮件时就出现了一系列问题。
我在使用 javamail 发送了邮件之后,会再次通过 javamail 将其获取回来进行解析,由于发送操作不当,导致了解析就不是那么回事了。
接下来先看看正常的解析过程吧。关于邮件的解析,网上依然有很多例子。
private static void multipartmailparser(multipart mail) throws exception { int count = mail.getcount(); system.out.println("part count: " + count); for (int i = 0; i < count; i++) { bodypart bodypart = mail.getbodypart(i); //cid 解析 //cid 示例: <4a85b9c9$1$16af704cfc3$coremail$user_taohan$163.com> string[] cids = bodypart.getheader("content-id"); system.out.println("=========> cids: " + (cids == null ? "null" : cids.length)); string content = "", cid = ""; if (cids != null && cids.length > 0) { content = cids[0]; if (content.startswith("<") && content.endswith(">")) { cid = "cid:" + content.substring(1, content.length() - 1); } else { cid = "cid:" + content; } } system.out.println(content+"---"+cid); system.out.println(bodypart.getcontenttype()); if (bodypart.ismimetype("text/plain")) { system.out.println("纯文本邮件: " + bodypart.getcontent()); } else if (bodypart.ismimetype("text/html")) { system.out.println("html邮件: " + bodypart.getcontent()); } else if (bodypart.ismimetype("multipart/*")) { multipart part = (multipart)bodypart.getcontent(); multipartmailparser(part); } else if (bodypart.ismimetype("application/octet-stream")) { string disposition = bodypart.getdisposition(); system.out.println("任意的二进制数据: " + disposition); //这里就是对附件进行解析 if (disposition.equalsignorecase(bodypart.attachment)) { string filename = bodypart.getfilename(); system.out.println("------------------------保存附件 " + filename); inputstream is = bodypart.getinputstream(); file file = new file("c:\\users\\ab\\desktop\\mail\\"+filename); copy(is, new fileoutputstream(file)); } } else if (bodypart.ismimetype("image/*") && !("".equals(cid))) { //内嵌图片处理 datahandler datahandler = bodypart.getdatahandler(); string name = datahandler.getname(); system.out.println("内嵌图片 name: " + name); inputstream is = datahandler.getinputstream(); file file = new file("c:\\users\\ab\\desktop\\mail\\"+name); copy(is, new fileoutputstream(file)); } } } private static void copy(inputstream is, outputstream os) throws ioexception { byte[] bytes = new byte[1024]; int len = 0; while ((len=is.read(bytes)) != -1 ) { os.write(bytes, 0, len); } if (os != null) os.close(); if (is != null) is.close(); }
使用以上方法对邮件进行解析是没有问题的,内嵌图片、附件都是可以分开解析的。但在我解析通过 javamail 发送的邮件时就出现了问题。
先看看最初是怎么发送的吧。这里就不贴完整代码了,我就是按照文章开始链接对应的文章进行了修改。
//这里只给出附件节点创建方法吧 //给出参数accessory(附件信息)格式为: zxd.jpg-c:/users/ab/desktop/zxd.jpg,lyf.jpg-c:/users/ab/desktop/lyf.jpg,htmlfile-c:/users/ab/desktop/file.html,golang-c:/users/ab/desktop/demo.go private list<mimebodypart> mailattachmentparts(string accessory) throws messagingexception, unsupportedencodingexception { //附件节点集合 list<mimebodypart> attachments = new arraylist<>(); mimebodypart attachment; datahandler dh; string[] accs = accessory.split(","); for (final string acc : accs) { string[] ac = acc.split("-"); //按照网上文章的例子,这里只需要进行如下设置即可 attachment = new mimebodypart(); dh = new datahandler(new filedatasource(ac[1])); attachment.setdatahandler(dh); attachments.add(attachment); } return attachments; }
发送后,查看去邮件服务器中查看,邮件是正常的。但是我再通过 javamail 获取就出现问题了。输出如下:(//…为我给出的注释)
part count: 5 =========> cids: null --- multipart/related; boundary="----=_part_2_1562389956.1559641692502" part count: 2 =========> cids: null --- text/html; charset=utf-8 //邮件内容正常获取 html邮件: <html><body><h1>这是邮件发送测试十二</h1><b>这依然是刘亦菲</b><br><br><br><img src='cid:liuyifei' /></body></html> //内嵌图片也正常获取 =========> cids: 1 liuyifei---cid:liuyifei image/jpeg; name=lyf2.jpg 内嵌图片 name: lyf2.jpg =========> cids: null --- image/jpeg; name=zxd.jpg //附件图片获取失败, 可以看见前面为 image/jpeg,也就是说 javamail 并没有将其作为附件进行处理 =========> cids: null --- image/jpeg; name=lyf.jpg //附件图片获取失败 =========> cids: null --- //最可笑的是居然将我的 file.html 文件当做了 text/html 来进行了处理, 没有将 html 文件保存到本地,而是直接输出了其中的内容 //我在手机邮件app中查看这封邮件的时候, 我的邮件内容并不是上面打印的内容, 而是这个 html 文件中的内容 text/html; charset=us-ascii; name=file.html html邮件: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>file upload</title> </head> <body> <div> <form action="http://localhost:8080/api/mail/record/accessory/upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="submit"> </form> </div> </body> </html> //但奇怪的是 demo.go 这个文件又被正常的当做了附件处理 //到这里就大概知道其中的原因了 //上面的 图片和html 文件都是比较特殊的, 但是 demo.go 就不一样了 =========> cids: null --- application/octet-stream; name=demo.go 任意的二进制数据: attachment ------------------------保存附件 demo.go
于是,我将需要发送的邮件保存至本地, message.writeto(new fileoutputstream("d/mail.eml")) 即可;
打开查看其中的内容发现
附件都有如下内容:
content-type: image/jpeg; name=lyf.jpg content-transfer-encoding: base64 content-disposition: attachment; filename=lyf.jpg ————————————————————— content-type: application/octet-stream; name=demo.go content-transfer-encoding: base64 content-disposition: attachment; filename=demo.go
而对比上面获取邮件的输出内容,只有 demo.go 这一个文件输出了 application/octet-stream 字样, 所以问题就已经变得很明显了。
只需要在创建附件节点时,为附件节点设置以下几样东西即可
attachment.setfilename(mimeutility.encodetext(dh.getname())); //附件名称 attachment.setdisposition(bodypart.attachment); //设置 disposition 为 attachment (附件标识) attachment.setheader("content-disposition", "attachment; filename="+dh.getname()); //设置以下两个 header attachment.setheader("content-type", "application/octet-stream; name="+dh.getname());
再看获取邮件输出:
part count: 5 =========> cids: null ---multipart/related; boundary="----=_part_2_1714832523.1559700934372" part count: 2 =========> cids: null --- text/html; charset=utf-8 html邮件: <html><body><h1>这是邮件发送测试十四</h1><b>这依然是刘亦菲</b><br><br><br><img src='cid:liuyifei' /></body></html> =========> cids: 1 liuyifei---cid:liuyifei image/jpeg; name=lyf2.jpg 内嵌图片 name: lyf2.jpg =========> cids: null --- application/octet-stream; name=zxd.jpg 任意的二进制数据: attachment ------------------------保存附件 zxd.jpg =========> cids: null --- application/octet-stream; name=lyf.jpg 任意的二进制数据: attachment ------------------------保存附件 lyf.jpg =========> cids: null --- application/octet-stream; name=file.html 任意的二进制数据: attachment ------------------------保存附件 file.html =========> cids: null --- application/octet-stream; name=demo.go 任意的二进制数据: attachment ------------------------保存附件 demo.go
这下就正常了,其实解决办法就是添加上面几样配置即可。
总结
以上所述是小编给大家介绍的javamail发送邮件后再通过javamail接收格式问题,希望对大家有所帮助
下一篇: 减肥的十大误区你踩雷了吗