关于JavaMail邮件开发
目的:实现程序自动发送邮件
预备知识
邮件服务器按通讯协议可以划分为两种类型:
- SMTP服务器 (发送邮件)
- SMTP协议,全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与SMTP服务器之间、以及两台SMTP服务器之间的通讯规则。
- POP3/IMAP服务器 (接收)
- POP3协议,全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则。
- IMAP协议,全称为Internet Message Access Protocal(Internet消息访问协议),它是对POP3协议的一种扩展,定义了邮件客户端软件与IMAP服务器的通讯规则
JavaMail介绍
要自己写程序发送和接收邮件,可以直接采用Socket编程连接上远程的邮件服务器,然后按照邮件协议与邮件服务器进行交互,涉及较多细节。另外,要想自己编程创建出复杂的MIME格式的邮件,是一件非常困难和麻烦的事情。
JavaMail 是Sun公司为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如SMTP、POP3、IMAP
JavaMail 也提供了能够创建出各种复杂MIME格式的邮件内容的相关API。
JavaMail API按其功能划分通常可分为如下三大类:
- 创建和解析邮件内容的API : Message类是创建和解析邮件的核心API,它的实例对象代表一封电子邮件。
- 发送邮件的API: Transport类是发送邮件的核心API类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如SMTP协议。
- 接收邮件的API: Store类是接收邮件的核心API类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如POP3协议。
Session类
Session类用于定义整个应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,如邮件服务器的主机名、端口号、采用的邮件发送和接收协议等。Session对象根据这些信息构建用于邮件收发的Transport和Store对象,以及为客户端创建Message对象时提供信息支持。
使用JavaMail发送一封简单的邮件:
- 创建包含邮件服务器的网络连接信息的Session对象。
- 创建代表邮件内容的Message对象。
- 创建Transport对象、连接服务器、发送Message、关闭连接
MIME协议
MIME,英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范,在MIME出现之前,互联网电子邮件主要遵循由RFC 822所制定的标准,电子邮件一般只用来传递基本的ASCII码文本信息,MIME在 RFC 822的基础上对电子邮件规范做了大量的扩展,引入了新的格式规范和编码方式,在MIME的支持下,图像、声音、动画等二进制文件都可方便的通过电子邮件来进行传递,极大地丰富了电子邮件的功能。目前互联网上使用的基本都是遵循MIME规范的电子邮件。
邮件开发准备
- 本地搭建一个邮件服务器
- 易邮服务器,eyoumailserversetup.exe
- 新建邮箱账号
- 新建域名
- 新建邮箱账号
邮件开发
-
JavaMail开发先引入jar文件
- activation.jar 【如果使用jdk1.6或以上版本,可以不用这个jar文件】
-
mail.jar 【邮件发送核心包】
/** * JavaMail测试,发送普通邮件 * @throws Exception */ @Test public void testMail() throws Exception { Properties props = new Properties(); props.put("mail.transport.protocol", "smtp"); // 指定协议 props.put("mail.smtp.host", "localhost"); // 主机 stmp.qq.com props.put("mail.smtp.auth", "true"); // 用户密码认证 props.put("mail.debug", "true"); // 调试模式 props.put("mail.smtp.port", 25); // 创建一个邮件会话 session Session session = Session.getDefaultInstance(props); // 创建邮件体对象 MimeMessage message = new MimeMessage(session); // 设置邮件体参数 // 标题 message.setSubject("测试邮件"); // 发送时间 message.setSentDate(new Date()); // 发件人 message.setSender(new InternetAddress("zhangsan@wsk.com")); // 收件人 message.setRecipient(RecipientType.TO, new InternetAddress("lisi@wsk.com")); // 内容 message.setContent("<a href='#'>百度</a>", "text/html;charset=UTF-8"); message.saveChanges(); // 保存邮件(可选) // 发送 Transport transport = session.getTransport(); transport.connect("zhangsan","888"); transport.sendMessage(message, message.getAllRecipients()); transport.close(); }
注意:当使用QQ邮件服务器时会有两个问题:
- QQ邮箱需要SSL
- QQ邮箱需要手动开启SMTP服务
SSL发送代码
// 设置SSL
prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.put("mail.smtp.socketFactory.fallback", "false");
prop.put("mail.smtp.port", "465");
示例代码如下:
/**
* JavaMail使用QQ邮件服务器发送邮件
* @throws Exception
*/
@Test
public void testSendQQ() throws Exception {
Properties prop = new Properties();
prop.put("mail.transport.protocol", "smtp"); // 指定协议
prop.put("mail.smtp.host", "smtp.qq.com"); // 主机 stmp.qq.com
prop.put("mail.smtp.auth", "true"); // 用户密码认证
prop.put("mail.debug", "true"); // 调试模式
// 设置SSL
prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.put("mail.smtp.socketFactory.fallback", "false");
prop.put("mail.smtp.port", "465");
// 创建一个邮件会话
Session session = Session.getDefaultInstance(prop);
// 创建邮件体对象(整封邮件)
MimeMessage message = new MimeMessage(session);
// 设置邮件体参数
// 标题
message.setSubject("带超链接的邮件邮件");
// 发送时间
message.setSentDate(new Date());
// 发件人
message.setSender(new InternetAddress("发件人邮箱"));
// 接收人
message.setRecipient(RecipientType.TO, new InternetAddress("收件人邮箱"));
// 内容
message.setContent("<a href='#'>百度</a>", "text/html;charset=UTF-8");
message.saveChanges();
// 发送
Transport trans = session.getTransport();
trans.connect("发件人", "QQ邮箱授权码");
// 发送邮件
trans.sendMessage(message, message.getAllRecipients());
trans.close();
}
发送带图片的邮件
/**
* JavaMail,发送资源文件
* @throws Exception
*/
@Test
public void testMailRs() throws Exception {
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp"); // 指定协议
props.put("mail.smtp.host", "localhost"); // 主机 stmp.qq.com
props.put("mail.smtp.auth", "true"); // 用户密码认证
props.put("mail.debug", "true"); // 调试模式
props.put("mail.smtp.port", 25);
// 创建一个邮件会话 session
Session session = Session.getDefaultInstance(props);
// 创建邮件体对象
MimeMessage message = new MimeMessage(session);
// 设置邮件体参数
// 标题
message.setSubject("测试邮件");
// 发送时间
message.setSentDate(new Date());
// 发件人
message.setSender(new InternetAddress("zhangsan@wsk.com"));
// 收件人
message.setRecipient(RecipientType.TO, new InternetAddress("lisi@wsk.com"));
// 内容
//**************************************************************************//
MimeMultipart related = new MimeMultipart("related");
// 构建多功能邮件块 内容和资源
MimeBodyPart content = new MimeBodyPart();
MimeBodyPart resource = new MimeBodyPart();
// 设置具体内容和资源
// 获取资源文件路径
String filePath = this.getClass().getResource("a.jpg").getPath();
DataSource ds = new FileDataSource(new File(filePath));
DataHandler handler = new DataHandler(ds);
resource.setDataHandler(handler);
resource.setContentID("a.jpg"); // 设置资源名称给外部引用
content.setContent("<img src='cid:a.jpg'/>图片!","text/html;charset=utf-8");
related.addBodyPart(content);
related.addBodyPart(resource);
/****************把复杂的邮件块添加到邮件中******************/
message.setContent(related);
message.saveChanges(); // 保存邮件(可选)
// 发送
Transport transport = session.getTransport();
transport.connect("zhangsan","888");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
发送带附件的邮件
/**
* 带附件的邮件
*/
@Test
public void testMailFile() throws Exception {
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp"); // 指定协议
props.put("mail.smtp.host", "localhost"); // 主机 stmp.qq.com
props.put("mail.smtp.auth", "true"); // 用户密码认证
props.put("mail.debug", "true"); // 调试模式
props.put("mail.smtp.port", 25);
// 创建一个邮件会话 session
Session session = Session.getDefaultInstance(props);
// 创建邮件体对象
MimeMessage message = new MimeMessage(session);
// 设置邮件体参数
// 标题
message.setSubject("测试邮件");
// 发送时间
message.setSentDate(new Date());
// 发件人
message.setSender(new InternetAddress("zhangsan@wsk.com"));
// 收件人
message.setRecipient(RecipientType.TO, new InternetAddress("lisi@wsk.com"));
// 内容
/**************************************************************************/
// 构建一个总的邮件块
MimeMultipart mixed = new MimeMultipart("mixed");
// 设置总的邮件块到对象中
message.setContent(mixed);
// 设置左右侧;左侧(文本+图片资源) 右侧(附件)
MimeBodyPart lift = new MimeBodyPart();
MimeBodyPart right = new MimeBodyPart();
// 将左右侧body添加到总邮件块中
mixed.addBodyPart(right);
mixed.addBodyPart(lift);
/*** 设置附件 ****/
String file = this.getClass().getResource("2015.pdf").getPath();
DataSource datasource = new FileDataSource(new File(file));
DataHandler data = new DataHandler(datasource);
// 设置附件文件到right body中
right.setDataHandler(data);
// 设置附件在邮件中的文件名
right.setFileName("2015.pdf");
// 构建related块,存放文本和图片
MimeMultipart related = new MimeMultipart("related");
// 将related块添加到lift body中
lift.setContent(related);
// 构建多功能邮件块 内容和资源
MimeBodyPart content = new MimeBodyPart();
MimeBodyPart resource = new MimeBodyPart();
// 设置具体内容和资源
// 获取资源文件路径
String filePath = this.getClass().getResource("a.jpg").getPath();
DataSource ds = new FileDataSource(new File(filePath));
DataHandler handler = new DataHandler(ds);
resource.setDataHandler(handler);
resource.setContentID("a.jpg"); // 设置资源名称给外部引用
content.setContent("<img src='cid:a.jpg'/>图片!","text/html;charset=utf-8");
related.addBodyPart(content);
related.addBodyPart(resource);
/****************把复杂的邮件块添加到邮件中******************/
message.saveChanges(); // 保存邮件(可选)
// 发送
Transport transport = session.getTransport();
transport.connect("zhangsan","888");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}