最近做了一个邮件发送功能,需要将查出的数据以邮件中附件的形式发送出去。记录下相关知识。同时相应的工具包将在 KUTILS 的下一个版本 kutils-0.0.6 中进行发布,引用地址
<dependency>
<groupId>com.github.kenny-tang</groupId>
<artifactId>kutils</artifactId>
<version>0.0.5</version>
</dependency>
如有任何意见和建议,都热烈欢迎,想要帮助完善代码的请联系我 kenny-tang@hotmail.com
JavaMail 介绍
JavaMail 为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如SMTP,POP3,IMAP,还有MIME等。
更多关于 email 历史的介绍可以参考邮件发送的基本过程与概念
1. 添加依赖包
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
2. 编写辅助类
关于 JAVA 发邮件网上有很多文章可以提供参考,这里我们把相关的东西做成类似于工具的东西,让不需要复杂功能的人可以直接拿过来使用。
首先可以将邮件的发送过程分成三个步骤
- 认证
这里主要是填写邮件发送人的信息,用户名、用户密码、使用的协议、端口等信息 - 发送邮件
填写收件人、邮件主题、邮件正文、附件,然后发出后 - 关闭连接
关闭连接
其中第一步的东西很难进行抽象,这些东西针对不同的人,不同的公司,不同的邮件服务商都是不同的,只能由实际的应用决定。但是第二步的过程是可以抽象出来的,可以做成一个简单的辅助工具。
2.1 邮件对象
将邮件抽象成一个类,主要包含收件人、邮件主题、邮件正文、附件等属性。
关于附件使用最多的是从文件系统中读取附件内容和从流中读取数据,针对不同的使用场景。
public class Email {
private static Logger logger = org.slf4j.LoggerFactory.getLogger(Email.class);
// 发件人地址
private String fromAddress;
// 邮件主题
private String subject;
// 邮件内容
private String content;
// 收件人列表
private List<String> receiveList;
// 附件列表
private List<Attachment> attachments;
/**
*
* @param session 可使用进行认证的session
* @param fromAddress 发件人
* @param subject 邮件主题
* @param content 邮件正文
* @param receiveList 收件人列表
*/
public void send(Session session) {
MimeMessage message = new MimeMessage(session);
InternetAddress[] toArray = new InternetAddress[receiveList.size()];
try {
// 接收列表
for (int i = 0; i < toArray.length; i++) {
toArray[i] = new InternetAddress(receiveList.get(i));
}
message.setSubject(subject);
message.setSentDate(new Date());
message.setFrom(new InternetAddress(fromAddress, subject));
message.addRecipients(RecipientType.TO, toArray);
// 创建多重消息
Multipart multipart = new MimeMultipart();
// 创建消息部分
// 设置文本消息部分
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(content, "text/html;charset=utf-8");
multipart.addBodyPart(messageBodyPart);
if (attachments != null && attachments.size() > 0) {
for (Attachment attachment : attachments) {
// 附件部分
messageBodyPart = new MimeBodyPart();
// 设置要发送附件的文件路径
DataSource source = getDataSource(attachment);
messageBodyPart.setDataHandler(new DataHandler(source));
// 处理附件名称中文(附带文件路径)乱码问题
messageBodyPart.setFileName(MimeUtility.encodeText(attachment.getFilename()));
multipart.addBodyPart(messageBodyPart);
}
}
// 发送完整消息
message.setContent(multipart);
// 发送消息
Transport.send(message);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private DataSource getDataSource(Attachment attachment) throws IOException {
if (attachment.getAttachmentFile() != null) {
return new FileDataSource(attachment.getAttachmentFile());
}
if (attachment.getAttachmentBytes() != null) {
return new ByteArrayDataSource(attachment.getAttachmentBytes(), attachment.getMimeType());
}
if (attachment.getInputStream() != null) {
return new ByteArrayDataSource(attachment.getInputStream(), attachment.getMimeType());
}
throw new RuntimeException("there is not attachment found, or it is not support yet, please check your code !");
}
// setter and getter
}
2.1 附件对象
这里只写了三种最常用的附件类型:
- 文件类型附件
附件存放与文件系统 - 字节类型附件
附件的内容我们可以以字节数据的形式获取 - 流类型附件
附件的内容可以从输入流中获取,这个本质上是和第二种类型的数据是相同的
public class Attachment {
// 文件类型附件
private File attachmentFile ;
// 字节流类型附件
private byte[] attachmentBytes;
// 输入流类型附件
private InputStream inputStream ;
// 文件MIME类型
private String mimeType ;
// 附件名称
private String filename ;
// setter and getter
}