700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java 发送邮件 格式_JavaMail发送邮件后再通过JavaMail接收格式问题

java 发送邮件 格式_JavaMail发送邮件后再通过JavaMail接收格式问题

时间:2020-10-21 09:46:52

相关推荐

java 发送邮件 格式_JavaMail发送邮件后再通过JavaMail接收格式问题

关于 JavaMail 如何发送邮件这里就不赘述了,网上有很多例子。其中最复杂的邮件发送莫过于 html邮件包含内嵌图片以及附件,最近项目中的这项功能我在发送邮件时就出现了一系列问题。

我在使用 JavaMail 发送了邮件之后,会再次通过 JavaMail 将其获取回来进行解析,由于发送操作不当,导致了解析就不是那么回事了。

接下来先看看正常的解析过程吧。关于邮件的解析,网上依然有很多例子。

private static void multipartMailParser(Multipart mail) throwsException {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$>

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("")) {

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,newFileOutputStream(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,newFileOutputStream(file));

}

}

}private static void copy(InputStream is, OutputStream os) throwsIOException {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 mailAttachmentParts(String accessory) throwsMessagingException, UnsupportedEncodingException {//附件节点集合

List attachments = new ArrayList<>();

MimeBodyPart attachment;

DataHandler dh;

String[] accs= accessory.split(",");for (finalString acc : accs) {

String[] ac= acc.split("-");//按照网上文章的例子,这里只需要进行如下设置即可

attachment = newMimeBodyPart();

dh= new DataHandler(new FileDataSource(ac[1]));

attachment.setDataHandler(dh);

attachments.add(attachment);

}returnattachments;

}

发送后,查看去邮件服务器中查看,邮件是正常的。但是我再通过 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: 1liuyifei---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邮件:

file upload

//但奇怪的是 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-8html邮件:

这是邮件发送测试十四

这依然是刘亦菲

=========> cids: 1liuyifei---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

这下就正常了,其实解决办法就是添加上面几样配置即可。

附件中文乱码解决

经过以上处理本以为正常了,但是附件又出现了中文乱码问题,在网上找了很多办法都不行,最终解决办法如下:

中文乱码问题:

网上的办法都是 bodyPart.setFileName(MimeUtility.encodeText(文件名)); 我也试过这种办法,但是未能奏效,最后通过下面的办法解决

//自己模拟一个 MimeUtility.encodeText() 返回的字符串

BASE64Encoder encoder = newBASE64Encoder();

String fileName="=?UTF-8?B?"+encoder.encode(dh.getName().getBytes("UTF-8"))+"?=";

bodyPart.setFileName(fileName);

attachment.setDisposition(BodyPart.ATTACHMENT); //设置 disposition 为 attachment (附件标识)

attachment.setHeader("content-disposition", "attachment; filename="+fileName); //设置以下两个 header, 这里也需要设置 base64 编码的文件名, JavaMail 默认就是使用的Base64编码文件名

attachment.setHeader("content-type", "application/octet-stream; name="+fileName);

获取的时候任然要使用 MimeUtility.decodeText(bodyPart.getFileName()) 对文件名进行解码

中文乱码过长问题:

这个的解决办法和网上方法一样,如下:

static{

System.setProperty("mail.mime.splitlongparameters","false");

}

具体原因自行百度了,多得很。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。