JavaMail实现邮件的回复
使用JavaMail提供的库javax.mail.*
来构造邮件的回复
实现简介
实现回复邮件,实际上就是实现邮件的发送,在邮件发送的基础上加上要回复邮件的信息,发送邮件的实现中存在一些坑,在后文中会有说明
构造一封邮件
首先是设置邮件的几个关键信息:from、to、cc、subject等等
Properties properties = new Properties();
properties.put("mail.host", "${邮件host}");
Session session = Session.getInstance(properties,null);//设置null代表不需要鉴权
final MimeMessage mimeMessage = new MimeMessage(session);
//设置发件人
mimeMessage.setFrom(new InternetAddress(${mail_from}));
//设置标题
mimeMessage.setSubject("${title}");
//设置收件人
mimeMessage.setRecipients(Message.Recipient.TO,${to_mail});
如果收件的邮箱对于收到的邮件header有其他要求,则按照要求添加header,如下所示:
mimeMessage.setHeader("IN-Reply-To", ${replyMessage});
构造邮件的subpart
JavaMail使用MimeMultipart这个类来构建邮件的subpart,如果要发送包含图片的html内容的邮件,需要将MimeMultipart设置为“relate”
String html = "${你构造的html内容}+${上一封邮件的html内容}";
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(html, "text/html; charset=gb2312");
MimeMultipart mimeMultipart = new MimeMultipart("relate");
mimeMultipart.addBodyPart(mimeBodyPart);
接下来是将图片从要回复的邮件中导出并导入到MimeMultipart这个类里:
MimeMessageParser oldEmailParser;//从原有的邮件导出
Collection<String> cidCollections = oldEmailParser.getContentIds();
if(Objects.nonNull(cidCollections)){
for (String cid : cidCollections){
DataSource dataSource = oldEmailParser.findAttachmentByCid(cid);
MimeBodyPart mimeBodyPart = new MimeBodyPart();
bodyPart.setDataHandler(new DataHandler(dataSource));
bodyPart.setHeader("Content-ID",cid);
bodyPart.setHeader("Content-Type", dataSource.getContentType());
bodyPart.setHeader("Content-Disposition", MimeBodyPart.INLINE);
bodyPart.setFileName(dataSource.getName());
mimeMultipart.addBodyPart(bodyPart);
}
}
对于整合出来的MimeMultipart类,再转成字符串如下所示:
mimeMessage.setContent(mimeMultipart);
ByteArrayOutputStream mime = new ByteArrayOutputStream();
mimeMessage.writeTo(mime);
String mimeStr = mime.toString();
生成mimeMessage后,再发送邮件即可。
遇到的问题
如果此时将上述代码生成的邮件发送给gmail或者outlook,对于中国用户,可能会出现邮件图片不显示的问题:
你可以尝试在outlook邮箱中使用富文本框添加图片,其中一个图片的命名为中文,一个图片的命名为英文,使用上文中所涉及到的代码,gmail收到的邮件中有图片无法显示:
查看邮件的源码:
我们发现源码中的附件,中文名命名的附件并没有被正确的显示,合理猜测可能是文件编码解码时发生了错误,将添加附件的代码改成如下所示,ISO-8859-1标准用来表示所有的欧区文字,邮箱就能正常显示了:
MimeMessageParser oldEmailParser;//从原有的邮件导出
Collection<String> cidCollections = oldEmailParser.getContentIds();
if(Objects.nonNull(cidCollections)){
for (String cid : cidCollections){
DataSource dataSource = oldEmailParser.findAttachmentByCid(cid);
MimeBodyPart mimeBodyPart = new MimeBodyPart();
String dataSourceName = new String(dataSource.getName().getBytes(), "ISO-8859-1");
bodyPart.setDataHandler(new DataHandler(dataSource));
bodyPart.setHeader("Content-ID",cid);
bodyPart.setHeader("Content-Type", dataSource.getContentType());
bodyPart.setHeader("Content-Disposition", MimeBodyPart.INLINE);
bodyPart.setFileName(dataSourceName);
mimeMultipart.addBodyPart(bodyPart);
}
}