今天我们使用 JavaMail 来实现发送邮件
首先了解2种基本协议:
smtp 服务器 : 一般是发件服务器, 端口一般为 25
pop3 服务器:一般是收件服务器,端口一般为 110
当然还有其他像 IMAP 等
常见SMTP服务器地址:
smtp.163.com 163 邮箱
smtp.qq.com 腾讯邮箱
可以使用 [telnet smtp.163.com 25] 做连通测试。其实可以直接使用 telnet 发送邮件,方法自行百度。
正式开讲:
首先下载 JAR 包:
JavaMail 下载地址: https://github.com/javaee/javamail/releases
整体目录结构:
创建 SendMail 类:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import sun.misc.BASE64Encoder;
public class SendMail {
// 发件账户信息
static String account = "m157********@163.com";
static String pwd = "z******0";
static String smtpHost = "smtp.163.com";
// 收件人邮箱
static String receiveAccount = "15******34@qq.com";
public static void main(String[] args) throws MessagingException, IOException {
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.host", smtpHost);
props.setProperty("mail.smtp.auth", "true");
// 使用 ssl 连接的话,将下面注释打开
// SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,
// 需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,
// QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
/*
* final String smtpPort = "465"; props.setProperty("mail.smtp.port",
* smtpPort); props.setProperty("mail.smtp.socketFactory.class",
* "javax.net.ssl.SSLSocketFactory");
* props.setProperty("mail.smtp.socketFactory.fallback", "false");
* props.setProperty("mail.smtp.socketFactory.port", smtpPort);
*/
// 创建会话对象,和服务器交互
Session session = Session.getDefaultInstance(props);
session.setDebug(true);
MimeMessage message = createMail(session, account, receiveAccount);
// 由 session 获取邮件传输对象
Transport transport = session.getTransport();
transport.connect(account, pwd);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
System.out.println("邮件发送完毕!");
// 将邮件保存到本地
saveLocal(message);
}
static MimeMessage createMail(Session session, String sendMail, String receiveMail)
throws MessagingException, IOException {
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(sendMail, "zhao.163", "utf--8"));
mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "zhao.qq", "utf-8"));
mimeMessage.setSubject("打折钜惠", "utf-8");
// 获取图片资源
FileInputStream in = new FileInputStream("resources/img/IMG_0323.GIF");
byte[] data = new byte[in.available()];
in.read(data);
in.close();
BASE64Encoder encoder = new BASE64Encoder();
String imgStr = encoder.encode(data);
imgStr = "data:image/gif;base64," + imgStr;
System.out.println("图片编码字符串:" + imgStr);
mimeMessage.setContent("" + "<h1>打折啦!</h1>" + "<p>打8.5折,快来抢购~</p><div>" + "<img src='" + imgStr + "'></div>",
"text/html;charset=utf-8");
mimeMessage.setSentDate(new Date());
mimeMessage.saveChanges();
return mimeMessage;
}
// 将邮件保存到本地
private static void saveLocal(MimeMessage message) throws IOException, MessagingException {
OutputStream out = new FileOutputStream("d:/mail.eml");
message.writeTo(out);
out.flush();
out.close();
}
}
收件:
以上实现了发送 HTML 格式的邮件,并且使用 base64 对图片进行了编码。同时在 D 盘将我们的邮件保存了下来,可以使用文本工具查看,到底邮件文件的格式是什么样的。
实际项目中不可能将 账户,服务器地址,用户名,密码这些写死到程序中,可以将SMTP服务器地址,邮件账户这些配置信息写到专门的配置文件中,每次程序从配置文件中读取,这样就方便多了。
注意如果使用腾讯邮箱作为发件方,那么密码需要使用腾讯邮箱提供的授权码,授权码到网页版腾讯邮箱设置中获取即可。