本文记录的是如何使用java实现发送简单文本内容邮件给一个或者多个联系人。邮件服务 Java API 支持使用 JavaMail(javax.mail)接口来发送电子邮件。

在使用javax.mail接口时,需要设置发件人,涉及到发件人的授权认证,于是创建了MailAuthenticator类,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package cn.cugb.edu.sendmail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MailAuthenticator extends Authenticator {
//|username| 邮箱用户名
private String username;
//|password| 邮箱密码
private String password;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

//构造函数
public MailAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}

@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}

上述类中usernamepassword字段就是发件人的邮箱用户名和密码,PasswordAuthentication是为Authenticator所用的数据容器,是存储用户名和密码的简要数据仓库。该类的主要作用就是验证发件人的信息。真正执行发送邮件的代码由SendMail类处理,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package cn.cugb.edu.sendmail;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

public class SendMail {
/**
* 发送邮件的props文件
*/
private Properties props = System.getProperties();
/**
* 邮件服务器登录验证
*/
private MailAuthenticator authenticator;
/**
* 邮箱session
*/
private Session session;

public SendMail(String username, String password) {
String smtpHostName = "smtp." + username.split("@")[1];
// 初始化props
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.host", smtpHostName);
// props.setProperty("mail.smtp.connectiontimeout", "10000");
// props.setProperty("mail.smtp.timeout", "10000");
// 验证
authenticator = new MailAuthenticator(username, password);
// 创建发送邮件的会话session
session = Session.getInstance(props, authenticator);
}

public boolean sendMail(String recipient, String subject, String sendContent) {
boolean isSended = false;

try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(authenticator.getUsername(), "Carya"));
message.setRecipient(RecipientType.TO, new InternetAddress(recipient, "Xiao Hong"));
message.setSubject(subject);
message.setSentDate(new Date());
message.setContent(sendContent, "text/html;charset=utf-8");
Transport.send(message);
isSended = true;
} catch (MessagingException e) {
isSended = false;
} catch (UnsupportedEncodingException e) {
isSended = false;
e.printStackTrace();
}

return isSended;
}

public static void main( String[] args ) {
SendMail sendMail = new SendMail("you-email@126.com", "you-password");
sendMail.sendMail("youRecipent@qq.com", "Hello, Nice", "Believe me, i am so good!");
}
}

其中类中props用于设置发件人邮件服务器的属性值,其中mail.smtp.auth设置为true,表示必须进行授权校验,该值默认是false; mail.smtp.host设置邮件服务器的Host值,然后创建用于验证发件人的MailAuthenticator对象以及邮件发送会话的Session对象.

邮件内容的主体是使用MimeMessage对象来表示,可设置邮件的发件人,收件人,邮件主题,邮件文本内容,发送邮件的时间等,然后使用Transport类的静态方法send()来发送MimeMessage对象。对邮件服务的调用为异步方式,且立即返回,邮件服务管理联系收件人的邮件服务器和交付邮件的过程,如果在将邮件发送到任何收件人时发生问题,或者收件人的邮件服务器返回"退回"讯息,则发件人将收到错误讯息。

设置收件人的类型MimeMessage.RecipientType时,有三种情况:

  • RecipientType.TO: 主要收件人
  • RecipientType.CC: 抄送人
  • RecipientType.BCC: 密送人,可用来隐藏收件人的信息,其它收件人看不到密送人的信息

最后的主函数中,设计测试用例来测试发邮件程序,需要将SendMail构造函数参数和方法调用中的收件人修改为真实的信息。

当邮件有多个收件人,将调用MimeMessagesetRecipient(RecipientType type, Address address)方法更改为setRecipients(RecipientType type, Address[] addresses),该方法接收Address[] addresses参数,存储邮件多个收件人列表。相应代码修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(authenticator.getUsername(), "Carya"));
message.setSubject(subject);
message.setContent(sendContent, "text/html;charset=utf-8");
message.setSentDate(new Date());
final int num = recipients.size();
InternetAddress[] addresses = new InternetAddress[num];
for (int i = 0; i < num; i++) {
addresses[i] = new InternetAddress(recipients.get(i));
}
message.setRecipients(RecipientType.TO, addresses);
Transport.send(message);