Java邮件发送

Java Mail 简介

常见的邮件协议包括:

  1. SMTP(Simple Mail Transfer Protocol):即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
  2. POP3(Post Office Protocol - Version 3):即邮局协议版本 3 ,用于接收电子邮件的标准协议。
  3. IMAP(Internet Mail Access Protocol) :即 Internet 邮件访问协议。是 POP3 的替代协议。

这三种协议都有对应SSL加密传输的协议,分别是 SMTPS,POP3S 和 IMAPS 。

MIME(Multipurpose Internet Mail Extensions) :即多用途因特网邮件扩展标准。它不是邮件传输协议。但对传输内容的消息、附件及其它的内容定义了格式。

JavaMail 是由 Sun(现 Oracle) 发布的用来处理 email 的 API 。它并没有包含在 Java SE 中,而是作为 Java EE 的一部分。JavaMail下载地址

下载的文件内容如下:

README.txt:整体介绍JavaMail,需要看一下
docs/javadocs:The JavaMail API javadocs,需要看一下
mail.jar:包括JavaMail API和所有service providers,大部分用户只需要该jar包
lib/mailapi.jar :只有JavaMail API
lib/imap.jar:The IMAP service provider
lib/smtp.jar:The SMTP service provider
lib/pop3.jar:The POP3 service provider
lib/dsn.jar:multipart/report DSN message support
demo:demo示例,简单了解,有需要再看

邮件传输过程

邮件的传输过程如下图:

transport

可以看出,收发邮件的步骤如下:
创建一个 Session 对象。
Session 对象创建一个 Transport 对象 /Store 对象,用来发送 / 保存邮件。
Transport 对象 /Store 对象连接邮件服务器。
Transport 对象 /Store 对象创建一个 Message 对象 ( 也就是邮件内容 ) 。
Transport 对象发送邮件; Store 对象获取邮箱的邮件。

可以看出,JavaMail 核心类包括:

javax.mail.Session:上下文环境信息,如服务器的主机名、端口号、协议名称等
javax.mail.Message:邮件模型,发送邮件和接收邮件的媒介,封装了邮件的信息,如发件人、收件人、邮件标题、邮件内容等
javax.mail.Transport:连接邮件SMTP服务器,发送邮件
javax.mail.Store:连接邮件POP3、IMAP服务器,收取邮件

核心类介绍

Session

Session 表示一个邮件会话,主要作用包括两个方面:

接收各种配置属性信息:通过 Properties 对象设置的属性信息;
初始化 JavaMail 环境:根据 JavaMail 的配置文件,初始化 JavaMail 环境,以便通过 Session 对象创建其他重要类的实例。

Transport

Session 类中的 getTransport () 有多个重载方法,可以用来创建 Transport 对象。

connect : 如果设置了认证命令(mail.smtp.auth) ,那么使用 Transport 类的 connect 方法连接服务器时,则必须加上用户名和密码。
sendMessage : Transport 类的 sendMessage 方法用来发送邮件消息。
close : Transport 类的 close 方法用来关闭和邮件服务器的连接。

Store

Session 类中的 getStore () 有多个重载方法,可以用来创建 Store 对象。

connect : 同上
getFolder : Store 类的 getFolder 方法可以 获取邮箱内的邮件夹 Folder 对象
close : Store 类的 close 方法用来关闭和邮件服务器的连接。

Message

Message 是抽象类,多数情况下使用子类 javax.mail.internet.MimeMessage 。
MimeMessage 代表 MIME 类型的电子邮件消息。

要创建一个 Message ,需要将 Session 对象传递给 MimeMessage 构造器:
MimeMessage message = new MimeMessage(session);

setFrom :设置邮件的发件人
setRecipient :设置邮件的发送人、抄送人、密送人

三种预定义的地址类型是:
Message.RecipientType.TO :收件人
Message.RecipientType.CC :抄送人
Message.RecipientType.BCC :密送人

setSubject :设置邮件的主题
setContent :设置邮件内容
setText :如果邮件内容是纯文本,可以使用此接口设置文本内容。

Address

Address 用来确定信件地址。和 Message 一样, Address 也是个抽象类。常用的是 javax.mail.internet.InternetAddress 类。

若创建的地址只包含电子邮件地址,只要传递电子邮件地址到构造器就行了:Address address = new InternetAddress("[email address]");

Authenticator

要使用验证者 Authenticator,先创建一个抽象类的子类,并从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 实例。创建完成后,您必需向 session 注册 Authenticator 。然后,在需要认证的时候,就会通知 Authenticator 。

简单的例子

发送文本邮件

public static void main(String[] args) throws Exception {
    Properties prop = new Properties();
    prop.setProperty("mail.debug", "true");
    prop.setProperty("mail.host", MAIL_SERVER_HOST);
    prop.setProperty("mail.transport.protocol", "smtp");
    prop.setProperty("mail.smtp.auth", "true");
 
    Session session = Session.getInstance(prop);
    Transport ts = session.getTransport();
    ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress(MAIL_FROM)); 
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO)); // 邮件的收件人
    message.setRecipient(Message.RecipientType.CC, new InternetAddress(MAIL_CC)); // 邮件的抄送人
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(MAIL_BCC)); // 邮件的密送人
    message.setSubject("Subject"); 
    message.setText("Content");
 
    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

发送HTML邮件

public static void main(String[] args) throws Exception {
    Properties prop = new Properties();
    ... ... // Set properties
    Session session = Session.getInstance(prop); 
    Transport ts = session.getTransport();

    MimeMessage message = new MimeMessage(session);
    ... ... // Head of Message.
    
    String htmlContent = "<h1>Hello</h1>" + "<p>显示图片<img src='cid:abc.jpg'>1.jpg</p>";
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(htmlContent, "text/html;charset=UTF-8");
    MimeBodyPart image = new MimeBodyPart();
    DataHandler dh = new DataHandler(new FileDataSource("D://img.jpg"));
    image.setDataHandler(dh);
    image.setContentID("image.jpg");

    MimeMultipart mm = new MimeMultipart();
    mm.addBodyPart(text); 
    mm.addBodyPart(image);
    mm.setSubType("related");
    message.setContent(mm);
    message.saveChanges();

    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

发送带附件的邮件

public static void main(String[] args) throws Exception {
    ... ...
    MimeBodyPart text = new MimeBodyPart();
    text.setContent("邮件中有两个附件。", "text/html;charset=UTF-8");

    MimeMultipart mm = new MimeMultipart();
    mm.setSubType("related");
    mm.addBodyPart(text);

    String[] files = {"D://[04]Temp//img//1.jpg", "D://[04]Temp//img//2.jpg"};
    for(String filename : files) {
        MimeBodyPart attachPart = new MimeBodyPart();
        attachPart.attachFile(filename);  
        mm.addBodyPart(attachPart);
    }
    message.setContent(mm);
    message.saveChanges();
    ... ...
}

获取邮箱中的邮件

public class StoreMail {
    final static String USER = "robot"; // 用户名
    final static String PASSWORD = "password520"; // 密码
    public final static String MAIL_SERVER_HOST = "mail.***.com"; // 邮箱服务器
    public final static String TYPE_HTML = "text/html;charset=UTF-8"; // 文本内容类型
    public final static String MAIL_FROM = "[email protected]"; // 发件人
    public final static String MAIL_TO = "[email protected]"; // 收件人
    public final static String MAIL_CC = "[email protected]"; // 抄送人
    public final static String MAIL_BCC = "[email protected]"; // 密送人

    public static void main(String[] args) throws Exception {
        // 创建一个有具体连接信息的Properties对象
        Properties prop = new Properties();
        prop.setProperty("mail.debug", "true");
        prop.setProperty("mail.store.protocol", "pop3");
        prop.setProperty("mail.pop3.host", MAIL_SERVER_HOST);
        // 1、创建session
        Session session = Session.getInstance(prop);
        // 2、通过session得到Store对象
        Store store = session.getStore();
        // 3、连上邮件服务器
        store.connect(MAIL_SERVER_HOST, USER, PASSWORD);
        // 4、获得邮箱内的邮件夹
        Folder folder = store.getFolder("inbox");
        folder.open(Folder.READ_ONLY);
        // 获得邮件夹Folder内的所有邮件Message对象
        Message[] messages = folder.getMessages();
        for (int i = 0; i < messages.length; i++) {
            String subject = messages[i].getSubject();
            String from = (messages[i].getFrom()[0]).toString();
            System.out.println("第 " + (i + 1) + "封邮件的主题:" + subject);
            System.out.println("第 " + (i + 1) + "封邮件的发件人地址:" + from);
        }
        // 5、关闭
        folder.close(false);
        store.close();
    }
}

PS:注意

上述小栗子非本人所写,搬运自这里。大家可以通过这些例子了解Java Mail。

我写的例子中将Properties、SMTP服务器、群发用户名、要发送的内容等写入了配置文件中。
这里需要说明的是:由于本人的代码涉及文件操作以及集合操作等,涉及Java Mail以外的内容,不利于理解,所以本文的代码采用了搬运的方式。

本人的例子主要实现群发功能,目前还较为简单(未加入附件等),测试通过了向Gmail/QQ/163邮箱的邮件发送。如果有需要可以在这里下载源码。

文件列表说明
users.txt:存放要转发的用户名(本人已经处理了空行以及注释#
setting.properties:Session需要的上下文环境
hosts.properties:配置SMTP服务器
content.html:本人用于测试的发送内容
src/email/test:一些测试
src/email/joshua/util:用于读取配置、地址转换的工具
src/email/Sender:完成发送功能的类
src/email/Main:完成用户的输入输出,运行该类执行程序

测试结果

参考

JAVA MAIL发送邮件实例
JAVA MAIL实现Email的发送
JavaMail发送邮件的最简单示例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容