使用 JavaMail 发送邮件

在这里插入图片描述

  虽然现在的交流办公软件层出不穷,但是邮件的一些优势是即时通信软件无法取代的。邮件可以作为一个很好的凭证并且可以存档。在传输文件和大型复杂的场景下,大多数人还是会选择邮件。所以,在我们开发网站的时候肯定也要应用邮件服务。
  JavaMail是Sun发布的用来提供给开发者处理电子邮件相关的编程接口。其中用于处理电子邮件的核心类是: Session, Message, Address, Authenticator, Transport, Store, Folder等。Session定义了一个基本的邮件会话,它需要从 Properties 中读取类似于邮件服务器,用户名和密码等信息。另外,很好的实现了 JavaMail API 的框架有 James、Spring Mail。


一、邮件协议

  在使用 Java 实现发送邮件之前,我们应该先弄清有关邮件的各种协议和每种协议包含的属性,一般的情况下我们使用SMTP协议发送邮件,POP3协议接收邮件:

协议 作用 端口
SMTP 用于将邮件发送到服务器的协议 25
SMTPS 使用SSL协议加密的SMTP协议 465
POP3 将服务器上的邮件下载到客户端上并可以删除服务器上的邮件 110
POP3S 使用SSL协议加密的POP3协议 995
IMAP 从服务器读取邮件的协议,不能删除服务器上的邮件 143
IMAPS 使用SSL协议加密的IMAP协议 993

二、邮件的发送与接收

  邮件的服务流程可由下图所示:

图片来源 www.cnblogs.com/ysocean

  发送邮件时,发件人会发消息给邮件服务器中的 SMTP service 。这时有两种情况:如果邮件的收信人也是处于同一个域,比如,从 QQ 的邮箱发送给 QQ 的邮箱,SMTP service 只需要保存在自己服务器即可。如果邮件收信人是不同的域,比如,QQ 邮箱发送给 163 邮箱,QQ 的 SMTP service 需要找到 163 的 SMTP service 并使用 SMTP 协议发送。然后,163 服务器中的 SMTP service 收到邮件后保存在存储空间中,此时收信人可使用 POP3 service 下载邮件。


三、SMTP中的常用头属性

  在搭建后端或者一些服务的时候,会以发送邮件为主。所以本文主要介绍关于使用 SMTP 协议发送邮件的实现。有关于 SMTP 协议更多的具体内容,可以参见官方标准文件 RFC 5321

  一封邮件主要由邮件头和邮件体组成.邮件头包含了发件人、收件人、主题、时间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域。有点类似于我们经常使用的HTTP头。

含义 示例
Received 邮件的路由信息,由链路中的路由添加 -
From 发件人地址 From: xxx <xxx@xx.com>
To 收件人地址 To: xxx@xx.com
CC 抄送地址 CC: xxx@xx.com
BCC 密送地址 BCC: xxx@xx.com
Return-Path 邮件无法发送的回退地址 Return-Path: <xxx@xx.com>
Date 发件的日期和时间 Date: Mon, 11 Nov 2020 11:11:11 +0800 (CST)
MIME-Version MIME版本 MIME-Version: 1.0
Boundary 标识分割内容与信息的字符串 Boundary: "xxxxxxxxxxx"
Subject 邮件主题,用 Base64 编码 Subject: TWljcm9uIFN0dWRpbw==
Content-Type 内容的类型 Content-Type: text/html;charset=UTF-8
X-* 非标准的、自定义的域以 X- 开头 X-Priority: 1

三、JavaMail 代码实现

Maven Repository: javax.mail » javax.mail-api » 1.6.2

包 :

  • javax.mail.jar ( 依赖 activation.jar )
  • activation.jar

类:

  • java.util.Properties
  • javax.mail.Session
  • javax.mail.Transport
  • javax.mail.internet.InternetAddress
  • javax.mail.internet.MimeMessage
       
/*
** MimeMessage.RecipientType.TO  接收人
** MimeMessage.RecipientType.CC  抄送人
** MimeMessage.RecipientType.BCC 密送人
*/
        
try {

    Properties prop = new Properties();//创建Java配置对象
    prop.setProperty("mail.transport.protocol", "smtp");//传输协议
    prop.setProperty("mail.smtp.host", "smtp.xxx.com");//邮箱服务器地址
    prop.setProperty("mail.smtp.auth","true");//是否需要身份验证
    prop.setProperty("mail.debug", "true");//是否显示日志信息
    prop.setProperty("mail.smtp.port", "25");//发送邮件端口号

    Session session = Session.getDefaultInstance(prop);//使用配置对象获取会话对象

    MimeMessage msg = new MimeMessage(session);//获取消息对象
    msg.setSentDate(new java.util.Date());//设置发件日期
    msg.setFrom(new InternetAddress("xxx@xx.com","xxx"));//设置发件地址
    msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("xxx@xx.com"));//设置接收地址
    msg.addHeader("X-Company", "Produced By Micron Studio");//自定义头信息
    msg.setSubject("xxxxxxxx");//邮件主题 ( 即邮件标题 )
    msg.setContent("<html></html>","text/html");//邮件内容以及 Content-Type

    Transport trans = session.getTransport("smtp");//获取传输对象
    trans.connect("smtp.xxx.com","xxx@xx.com", "**********");//使用账户密码连接邮件服务器
    trans.sendMessage(msg, msg.getAllRecipients());//发送消息
    trans.close();//关闭对象
    
} catch (Exception e) {
    //异常处理
}
        

四、使用 SSL 协议加密 SMTP 报文 (SMTPS)

类:

  • com.sun.mail.util.MailSSLSocketFactory

  创建以下对象

MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);

  为 Properties 添加以下属性

prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
prop.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.setProperty("mail.smtp.socketFactory.fallback", "false");
prop.setProperty("mail.smtp.ssl.enable", "true");

  更改发送的端口号

prop.setProperty("mail.smtp.port", "465");
posted @ 2020-12-28 16:15  LegendLiuYC  阅读(92)  评论(0编辑  收藏  举报