现在的位置: 首页 > 编程语言 > 正文

浅析JavaMail发送邮件后再通过JavaMail接收格式问题

2020年02月14日 编程语言 ⁄ 共 5989字 ⁄ 字号 评论关闭

复杂邮件发送问题

关于 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.goprivate 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>这依然是刘亦菲<br><br><br><img src='cid:liuyifei' /></body></html>//内嵌图片也正常获取=========> cids: 1liuyifei---cid:liuyifeiimage/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.htmlhtml邮件: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>file upload</title></head><body> <p> <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> </p></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.jpgContent-Transfer-Encoding: base64Content-Disposition: attachment; filename=lyf.jpg—————————————————————Content-Type: application/octet-stream; name=Demo.goContent-Transfer-Encoding: base64Content-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()); //设置以下两个 headerattachment.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-8html邮件: <html><body><h1>这是邮件发送测试十四</h1>这依然是刘亦菲<br><br><br><img src='cid:liuyifei' /></body></html>=========> cids: 1liuyifei---cid:liuyifeiimage/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接收格式问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

本文标题: 浅析JavaMail发送邮件后再通过JavaMail接收格式问题

以上就上有关浅析JavaMail发送邮件后再通过JavaMail接收格式问题的全部内容,学步园全面介绍编程技术、操作系统、数据库、web前端技术等内容。

抱歉!评论已关闭.