要在网络上实现邮件功能,必须要有专门的邮件服务器。
这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
SMTP服务器地址:一般是 smtp.xxx.com
,比如163邮箱是smtp.163.com
,qq邮箱是smtp.qq.com
。
电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用qq邮箱,就需要开通邮箱功能;
SMTP协议:
发送邮件协议。
我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)
POP3协议:
接收邮件协议。
我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。
大狂神通过smtp协议连接到Smtp服务器,然后发送一封邮件给网易的邮件服务器
网易分析发现需要去QQ的邮件服务器,通过smtp协议将邮件转投给QQ的Smtp服务器
QQ将接收到的邮件存储在 [email protected]这个邮件账号的空间中
小狂神通过Pop3协议连接到Pop3服务器收取邮件
从 [email protected]这个邮件账号的空间中取出邮件
Pop3服务器将取出来的邮件送到小狂神手中
【注意】有可能你收件人地址,发件人地址等信息都正确了,控制台也打印了正确的信息,但是在收件箱就是收不到信息。这是因为可能收件箱服务器拒收了你发的邮件(比如认为你的邮件是广告),这时候可能在垃圾箱里能找到,可能找不到。解决办法是重复的邮件内容不要多次发送,或者更换收件箱试试
我们将用代码完成邮件的发送。这在实际项目中应用的非常广泛,比如注册需要发送邮件进行账号激活,再比如OA项目中利用邮件进行任务提醒等等。
使用Java发送 E-mail 十分简单,但是首先你应该准备 JavaMail API
和Java Activation Framework
。
得到两个jar包:mail.jar
和activation.jar
,导入lib
目录下。
我们这里使用qq邮箱发送邮件,QQ邮箱需要安全验证,我们需要获取他对应的权限。获取权限操作为:QQ邮箱–>邮箱设置–>账户
JavaMail 简介:
JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。
JavaMail 下载地址: https://github.com/javaee/javamail/releases
JavaMail API 分类:
按照功能可以划分为如下三大类:
这三种类型的API在 JavaMail 中由多个类组成,但是主要有四个核心类,我们在编写程序时,记住这四个核心类,就很容易编写出Java邮件处理程序。
JavaMail API 核心类:
①、Message 类:javax.mail.Message
类是创建和解析邮件的核心 API,这是一个抽象类,通常使用它的子类javax.mail.internet.MimeMessage
类。它的实例对象表示一份电子邮件。客户端程序发送邮件时,首先使用创建邮件的 JavaMail API
创建出封装了邮件数据的 Message 对象,然后把这个对象传递给邮件发送API(Transport 类) 发送。客户端程序接收邮件时,邮件接收API把接收到的邮件数据封装在Message 类的实例中,客户端程序在使用邮件解析API从这个对象中解析收到的邮件数据。
②、Transport 类:javax.mail.Transport
类是发送邮件的核心API 类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如 SMTP 协议,客户端程序创建好 Message 对象后,只需要使用邮件发送API 得到 Transport 对象,然后把 Message 对象传递给 Transport 对象,并调用它的发送方法,就可以把邮件发送给指定的 SMTP 服务器。
③、Store 类:javax.mail.Store
类是接收邮件的核心 API 类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如 POP3 协议,客户端程序接收邮件时,只需要使用邮件接收 API 得到 Store 对象,然后调用 Store 对象的接收方法,就可以从指定的 POP3 服务器获得邮件数据,并把这些邮件数据封装到表示邮件的 Message 对象中。
④、Session 类:javax.mail.Session
类用于定义整个应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,例如邮件服务器的主机名、端口号、采用的邮件发送和接收协议等。Session 对象根据这些信息构建用于邮件收发的 Transport 和 Store 对象,以及为客户端创建 Message 对象时提供信息支持。
JavaMail 发送邮件的步骤:
在理解通过代码实现邮件的发送时,我们可以将邮件发送假想为火箭运载着卫星发送。其中Message 是卫星,Transport 是火箭,而卫星和火箭的构建都需要 Session 的帮助,这样的关系更加便于记忆
代码实现:
package org.java.sendmail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.Properties;
public class SendMail {
public static void main(String[] args) throws MessagingException, GeneralSecurityException {
//创建一个配置文件保存并读取信息
Properties properties = new Properties();
//设置qq邮箱服务
properties.setProperty("mail.host","smtp.qq.com");
//设置发送协议
properties.setProperty("mail.transport.protocol","smtp");
//设置用户是否需要验证
properties.setProperty("mail.smtp.quth","true");
//关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
//===================准备工作完成
//1、创建以session会话对象
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
//发件人邮箱,授权码
return new PasswordAuthentication("发件箱","授权码");
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、获取连接对象,通过session对象获得ransport,需要捕获或者抛出异常
Transport transport = session.getTransport();
//3、连接服务器,抛出异常
transport.connect("smtp.qq.com","发件邮箱","授权码");
//4、连接之后,创建邮件
Message mimeMessage = getMimeMessage(session);
//5. 发送邮件
transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
//6 关闭连接
transport.close();
}
public static MimeMessage getMimeMessage(Session session) throws MessagingException {
//4.1 创建邮件对象
MimeMessage mimeMessage = new MimeMessage(session);
//4.2 邮件发送人
mimeMessage.setFrom(new InternetAddress("发件箱"));
//4.3 邮件接收人,可以同时发送给多人
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("收件箱")});
//4.4 邮件标题
mimeMessage.setSubject("hello mail");
//4.5 邮件内容
mimeMessage.setContent("快发论文", "text/html;charset=UTF-8");
return mimeMessage;
}
}
使用JavaMail发送邮件的代码实现步骤为:
- Step1:创建定义整个应用程序所需的环境信息的 Session 对象
- Step2:获取连接对象,通过session对象获得ransport
- Step3:连接服务器,使用邮箱的用户名和授权码连上邮件服务器,
- Step4:创建邮件
- 创建邮件对象
- 邮件发送人
- 邮件接收人
- 邮件标题
- 邮件内容
- Step5: 发送邮件
- Step6:关闭连接
先认识两个类一个名词:
MIME:多用途互联网邮件扩展类型
MimeBodyPart类:
javax.mail.internet.MimeBodyPart
类 表示的是一个MIME
消息,它和MimeMessage
类一样都是从Part接口继承过来。
MimeMultipart类:
javax.mail.internet.MimeMultipart
是抽象类 Multipart
的实现子类,它用来组合多个MIME
消息。一个MimeMultipart
对象可以包含多个代表MIME消息的MimeBodyPart
对象。
在纯文本中使用内嵌的方式显示一些图片,因此就要将纯文本和内嵌图片单独存放在MimeBodyPart
中然后再将其存放在一个Mimemultipart
对象中即可。
代码实现如下:
package org.java.sendmail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Properties;
public class SendImageMail {
public static void main(String[] args) throws Exception {
//创建一个配置文件保存并读取信息
Properties properties = new Properties();
//设置qq邮箱服务
properties.setProperty("mail.host", "smtp.qq.com");
//设置发送协议
properties.setProperty("mail.transport.protocol", "smtp");
//设置用户是否需要验证
properties.setProperty("mail.smtp.auth", "true");
// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
//=================================准备工作完毕
//1、创建以session会话对象
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("发件人邮箱","授权码");
}
});
//可以通过session开启Dubug模式,查看所有的过程
session.setDebug(true);
//2、获取连接对象,通过session对象获得ransport,需要捕获或者抛出异常
Transport transport = session.getTransport();
//3、连接服务器,抛出异常
transport.connect("smtp.qq.com", "发件人邮箱","授权码");
//4、创建邮件
MimeMessage mimeMessage = imageMail(session);
//5. 发送邮件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
//6 关闭连接
transport.close();
}
//邮件内容编写
public static MimeMessage imageMail(Session session) throws MessagingException {
//图片:需要通过数据流来实现
//1、准备图片
MimeBodyPart emaliBody1 = new MimeBodyPart();
//2、需要将图片变成数据
//2.1 获取图片的数据
FileDataSource fileDataSource = new FileDataSource("resourse/timg2.jpg");
//2.2 需要一个数据流的数据来处理
DataHandler imgData = new DataHandler(fileDataSource);
//2.3 把图片数据放到邮件消息内容中
emaliBody1.setDataHandler(imgData);
//2.4 给图片设置一个名字
emaliBody1.setContentID("小小孩.jpg");
//文本
MimeBodyPart emaliBody2 = new MimeBodyPart();
//给第二个邮件内容插入一个图片
emaliBody2.setContent("新京报快讯(记者 倪伟)据中国载人航天工程办公室消息
","text/html;charset=UTF-8");
//拼接邮件,描述关系
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(emaliBody1);
multipart.addBodyPart(emaliBody2);
//描述是什么类型的邮件
multipart.setSubType("related"); //这表示是一个带图片的邮件
MimeMessage mimeMessage = new MimeMessage(session);
//邮件发送人
mimeMessage.setFrom(new InternetAddress("发件人邮箱"));
//邮件接收人,可以同时发送给多人
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("收件人邮箱")});
//邮件标题
mimeMessage.setSubject("天宫二号回家");
mimeMessage.setContent(multipart);
mimeMessage.saveChanges(); //保存修改
return mimeMessage;
}
}
代码:
package org.java.sendmail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.security.GeneralSecurityException;
import java.util.Properties;
public class SendFileMail {
public static void main(String[] args) throws MessagingException, GeneralSecurityException {
//创建一个配置文件保存并读取信息
Properties properties = new Properties();
//设置qq邮箱服务
properties.setProperty("mail.host","smtp.qq.com");
//设置发送协议
properties.setProperty("mail.transport.protocol","smtp");
//设置用户是否需要验证
properties.setProperty("mail.smtp.auth","true");
// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
//=================================准备工作完毕
//1、创建以session会话对象
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("发件人邮箱","授权码");
}
});
//可以通过session开启Dubug模式,查看所有的过程
session.setDebug(true);
//2、获取连接对象,通过session对象获得ransport,需要捕获或者抛出异常
Transport transport = session.getTransport();
//3、连接服务器,抛出异常
transport.connect("smtp.qq.com", "发件人邮箱","授权码");
//4、创建邮件
MimeMessage mimeMessage = fileMail(session);
//5. 发送邮件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
//6 关闭连接
transport.close();
}
public static MimeMessage fileMail(Session session) throws MessagingException {
//4.1 创建邮件对象
MimeMessage mimeMessage = new MimeMessage(session);
//4.2 邮件发送人
mimeMessage.setFrom(new InternetAddress("发件人邮箱"));
//4.3 邮件接收人,可以同时发送给多人
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("收件人邮箱")});
//4.4 邮件标题
mimeMessage.setSubject("复杂的邮件");
//4.5 邮件内容
//编写邮件内容: 1.图片
// 2.附件
// 3.文本
//图片
MimeBodyPart body1 = new MimeBodyPart();
body1.setDataHandler(new DataHandler(new FileDataSource("src/resourse/timg3.jpg")));
body1.setContentID("小小孩3.jpg"); //图片设置ID,图片设置名字
//文本
MimeBodyPart body2 = new MimeBodyPart();
body2.setContent("请注意,我不是广告
","text/html;charset=UTF-8");
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("src/resourse/1.docx")));
body3.setFileName(MimeUtility.encodeText("学习文档")); //设置附件文件名,需要编码
//拼装邮件正文内容
MimeMultipart multipart1 = new MimeMultipart();
multipart1.addBodyPart(body1);
multipart1.addBodyPart(body2);
multipart1.setSubType("related"); //1.文本和图片内嵌成功!
//new MimeBodyPart().setContent(multipart1); //将拼装好的正文内容设置为主体
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(multipart1);
//拼接附件
MimeMultipart allFile =new MimeMultipart();
allFile.addBodyPart(body3); //附件
allFile.addBodyPart(contentText);//正文
allFile.setSubType("mixed"); //正文和附件都存在邮件中,所有类型设置为mixed;
//放到Message消息中
mimeMessage.setContent(allFile);
mimeMessage.saveChanges();//保存修改
return mimeMessage;
}
}