Flask接口签名sign原理与实例代码浅析
322
2023-01-05
浅析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(contenhttp://t+"---"+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
//附件节点集合
List
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邮件:
//内嵌图片也正常获取
=========> 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邮件:
//但奇怪的是 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邮件: &rrJLRVztKglt;body>
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~