JavaMail发送邮件(超详细)
⼀:邮件发送的基本概念
  本⽂我将阐述使⽤JavaMail⽅式发送和接收Email的详细说明,本博客本着以后遇到类似的邮件发送需求可以直接把代码粘过去直接使⽤,快捷⽅便省时间,对于刚接触的JavaMail的朋友们还是把⽂章过⼀遍,虽然本⽂不是最好的,但是我可以保证你能成功发送邮件;
  关于邮件还有⼀些基本知识我将在下⾯简单介绍,关于邮件发送和接收的流程可以参考
1:邮件中的⼏个名词
发件⼈:
指的是⽤哪个邮箱进⾏发送邮件的⼈
收件⼈:
指的是接收发件⼈发过来邮件的⼈,代表这封邮件⾯向的读者。可以是零个到多个。
抄送⼈:
指的是发件⼈把邮件发送给收件⼈的同时并抄送⼀份发给抄送⼈;此时抄送⼈可以看到收件⼈、抄送⼈的邮箱
密送⼈:
指的是发件⼈把邮件发送给收件⼈的同时并抄送⼀份发给密送⼈;此时抄送⼈可以看到收件⼈、抄送⼈的邮箱,⽆法看到密送⼈的邮箱
说明:抄送⼈和密送⼈⼀般⽤于项⽬组A给项⽬组B发送邮件确认流程,这时项⽬组A还要告知领导我已经把⽅案流程发送给项⽬组B了;
这时我就要把流程⽅案抄送⼀份给领导,就可以⽤到抄送和密送,此邮件领导是不⽤回复的
2:发送邮件的⼏种⽅式
JavaMail 具体使⽤说明参考Oracle官⽹给出的API:
Jakarta Mail 具体使⽤说明参考Jakarta官⽅给出的API:
1:javax.*
也是java标准的⼀部分,但是没有包含在标准库中,⼀般属于标准库的扩展。通常属于某个特定领域,不是⼀般性的api。
所以以扩展的⽅式提供api,以避免jdk的标准库过⼤。当然某些早期的javax,后来被并⼊到标准库中,所有也应该属于新版本JDK的标准库。
⽐如jmx,java5以前是以扩展⽅式提供,但是jdk5以后就做为标准库的⼀部分了,所有javax.management也是jdk5的标准库的⼀部分。
2:com.sun.*
是sun的hotspot虚拟机中java.* 和javax.*的实现类。因为包含在rt中,所以我们也可以调⽤。但是因为不是sun对外公开承诺的接⼝,
所以根据根据实现的需要随时增减,因此在不同版本的hotspot中可能是不同的,⽽且在其他的jdk实现中是没有的,调⽤这些类,
  可能不会向后兼容,⼀般不推荐使⽤
下⾯介绍的发送邮件的⼏种⽅式:
①:使⽤javax.mail的坐标依赖包(导包时看清楚是不是javax.mail的)
<!--JavaMail基本包-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!--邮件发送的扩展包-->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
注:坐标必须为两个,因为javax.mail没有携带依赖包javax.activation(发送)
②:使⽤com.sun.mail的坐标依赖包(不推荐使⽤,这⾥我没讲了,下⾯是它的坐标,坐标内携带javax.activation依赖)
<!-- mvnrepository/artifact/com.sun.mail/javax.mail -->
<!--使⽤Sun提供的Email⼯具包-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
③:使⽤Jakarta Mail发送邮件(和javax.mail使⽤⽅式基本⼀样,不过它内部携带了javax.activation依赖包)
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
  ③:使⽤SpringBoot集成邮件发送()
    注:SpringBoot集成邮件发送底层使⽤Jakarta Mail技术
注:javax.JavaMail最后⼀个版本发布于2018年8⽉,后期发送邮件最好使⽤Jakarta Mail(它是javaMail的前⾝);
总结:不借助SpringBoot的情况下使⽤ javax.JavaMail 或 Jakarta Mail ⽅式
⼆:JavaMailAPI简单说明
1:Session类
  javax.mail.Session类⽤于定义整个应⽤程序所需的环境信息,以及收集客户端与邮件服务器建⽴⽹络连接的会话信息,例如邮件服务器的主机名、端⼝号、采⽤的邮件发送和接收协议等。Session 对象根据这些信息构建⽤于邮件收发的Transport和Store对象,以及为客户端创建Message对象时提供信息⽀持。
Session getInstance(Properties props)
Session getInstance(Properties props, Authenticator authenticator)
说明:获取⼀个新的Session对象
参数:
props:为Session会话域提供默认值
mail.store.protocol:接收邮件时分配给协议的名称
mail.host:邮箱服务器地址
mail.user:发件⼈名称
mail.from:发件⼈邮箱
authenticator:
⽤于在需要⽤户名和密码时回调应⽤程序
2:Message类
  javax.mail.Message类是创建和解析邮件的核⼼API,这是⼀个抽象类,通常使⽤它的⼦类javax.mail.internet.MimeMessage类。它的实例对象表⽰⼀份电⼦邮件。客户端程序发送邮件时,⾸先使⽤创建邮件的JavaMail API创建出封装了邮件数据的Message对象,然后把这个对象传递给邮件发送API(Transport 类)发送,客户端程序接收邮件时,邮件接收API把接收到的邮件数据封装在Message类的实例中,客户端程序在使⽤邮件解析API从这个对象中解析收到的邮件数据。
3:Transport类
  javax.mail.Transport类是发送邮件的核⼼API类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如SMTP协议,客户端程序创建好Message对象后,只需要使⽤邮件发送API得到Transport对象,然后把Message对象传递给Transport 对象,并调⽤它的发送⽅法,就可以把邮件发送给指定的SMTP服务器。
4:Store类
  javax.mail.Store类是接收邮件的核⼼API类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如POP3协议,客户端程序接收邮件时,只需要使⽤邮件接收API得到Store对象,然后调⽤St
ore对象的接收⽅法,就可以从指定的POP3服务器获得邮件数据,并把这些邮件数据封装到表⽰邮件的 Message 对象中
三:使⽤javax中的JavaMail
1:基本坐标导⼊
<!--JavaMail基本包-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!--邮件发送的扩展包-->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
2:使⽤JavaMail发送HTML格式邮件
public class JavaxJavaMailClient {
public String emailHost = "smtp.163";      //发送邮件的主机
public String transportType = "smtp";          //邮件发送的协议
public String fromUser = "antladdie";          //发件⼈名称
public String fromEmail = "antladdie@163";  //发件⼈邮箱
public String authCode = "xxxxxxxxxxxxxxxx";    //发件⼈邮箱授权码
public String toEmail = "xiaofeng504@qq";  //收件⼈邮箱
public String subject = "电⼦专票开具";          //主题信息
@Test
public void ClientTestA() throws UnsupportedEncodingException, javax.mail.MessagingException {
//初始化默认参数
Properties props = new Properties();
props.setProperty("ansport.protocol", transportType);
props.setProperty("mail.host", emailHost);
props.setProperty("mail.user", fromUser);
props.setProperty("mail.from", fromEmail);
//获取Session对象
Session session = Instance(props, null);
//开启后有调试信息
session.setDebug(true);
//通过MimeMessage来创建Message接⼝的⼦类
MimeMessage message = new MimeMessage(session);
//下⾯是对邮件的基本设置
//设置发件⼈:
//设置发件⼈第⼀种⽅式:直接显⽰:antladdie <antladdie@163>
//InternetAddress from = new InternetAddress(sender_username);
//设置发件⼈第⼆种⽅式:发件⼈信息拼接显⽰:蚂蚁⼩哥 <antladdie@163>
String formName = deWord("蚂蚁⼩哥") + " <" + fromEmail + ">";
InternetAddress from = new InternetAddress(formName);
message.setFrom(from);
//设置收件⼈:
InternetAddress to = new InternetAddress(toEmail);
message.setRecipient(Message.RecipientType.TO, to);
//设置抄送⼈(两个)可有可⽆抄送⼈:
List<InternetAddress> addresses = Arrays.asList(new InternetAddress("1457034247@qq"), new InternetAddress("575814158@qq"));        InternetAddress[] addressesArr = (InternetAddress[]) Array();
message.setRecipients(Message.RecipientType.CC, addressesArr);
//设置密送⼈可有可⽆密送⼈:
//InternetAddress toBCC = new InternetAddress(toEmail);
//message.setRecipient(Message.RecipientType.BCC, toBCC);
//设置邮件主题
message.setSubject(subject);
//设置邮件内容,这⾥我使⽤html格式,其实也可以使⽤纯⽂本;纯⽂本"text/plain"
message.setContent("<h1>蚂蚁⼩哥祝⼤家⼯作顺利!</h1>", "text/html;charset=UTF-8");
//保存上⾯设置的邮件内容
message.saveChanges();
//获取Transport对象
Transport transport = Transport();
//smtp验证,就是你⽤来发邮件的邮箱⽤户名密码(若在之前的properties中指定默认值,这⾥可以不⽤再次设置)
//发送邮件
transport.sendMessage(message, AllRecipients()); // 发送
}
}
3:使⽤JavaMail发送HTML内携带图⽚邮件格式
public class JavaxJavaMailClient {
public String emailHost = "smtp.163";      //发送邮件的主机
public String transportType = "smtp";          //邮件发送的协议
public String fromUser = "antladdie";          //发件⼈名称
public String fromEmail = "antladdie@163";  //发件⼈邮箱
public String authCode = "xxxxxxxxxxxxxxxx";    //发件⼈邮箱授权码
public String toEmail = "xiaofeng504@qq";  //收件⼈邮箱
public String subject = "电⼦专票开具";          //主题信息
@Test
public void ClientTestB() throws IOException, javax.mail.MessagingException {
// 1:初始化默认参数
Properties props = new Properties();
props.setProperty("ansport.protocol", transportType);
props.setProperty("mail.host", emailHost);
props.setProperty("mail.user", fromUser);
props.setProperty("mail.from", fromEmail);
// 2:获取Session对象
Session session = Instance(props, null);
session.setDebug(true);
// 3:创建MimeMessage对象
MimeMessage message = new MimeMessage(session);
// 4:设置发件⼈、收件⼈、主题、(内容后⾯设置)
String formName = deWord("蚂蚁⼩哥") + " <" + fromEmail + ">";
InternetAddress from = new InternetAddress(formName);
message.setFrom(from);
InternetAddress to = new InternetAddress(toEmail);
message.setRecipient(Message.RecipientType.TO, to);
//设置邮件主题
message.setSubject(subject);
//邮件发送时间
message.setSentDate(new Date());
// 5:设置多资源内容
//=============== 构建邮件内容:多信息⽚段关联邮件使⽤Content-Type:multipart/related ===============// // 5.1:构建⼀个多资源的邮件块⽤来把⽂本内容资源和图⽚资源关联;;;related代表多资源关联
MimeMultipart text_img_related = new MimeMultipart("related");
//text_img_related.setSubType("related");
//注:这⾥为什么填写related的请去查阅Multipart类型或者去⽂章开头跳转我之前上⼀篇邮件介绍
// 5.2:创建图⽚资源
MimeBodyPart img_body = new MimeBodyPart();
DataHandler dhImg = new DataHandler(Resource("static/b.png"));
img_body.setDataHandler(dhImg); //设置dhImg图⽚处理
img_body.setContentID("imgA");  //设置资源图⽚名称ID
// 5.3:创建⽂本资源,⽂本资源并引⽤上⾯的图⽚ID(因为这两个资源我做了关联)
MimeBodyPart text_body = new MimeBodyPart();
text_body.setContent("<img src='cid:imgA' width=100/> 我是蚂蚁⼩哥!!","text/html;charset=UTF-8");
// 5.4:把创建出来的两个资源合并到多资源模块了
text_img_related.addBodyPart(img_body);
text_img_related.addBodyPart(text_body);
//===========================================================================================// // 6:设置我们处理好的资源(存放到Message)
message.setContent(text_img_related);
// 7:保存上⾯设置的邮件内容
message.saveChanges();
// 8:获取Transport对象
Transport transport = Transport();
//9:smtp验证,就是你⽤来发邮件的邮箱⽤户名密码(若在之前的properties中指定默认值,这⾥可以不⽤再次设置)
//10:发送邮件
transport.sendMessage(message, AllRecipients()); // 发送qq怎么发邮件
}
}
4:使⽤JavaMail发送HTML带图⽚+附件格式邮件
public class JavaxJavaMailClient {
public String emailHost = "smtp.163";      //发送邮件的主机
public String transportType = "smtp";          //邮件发送的协议
public String fromUser = "antladdie";          //发件⼈名称
public String fromEmail = "antladdie@163";  //发件⼈邮箱
public String authCode = "xxxxxxxxxxxxxxxx";    //发件⼈邮箱授权码
public String toEmail = "xiaofeng504@qq";  //收件⼈邮箱
public String subject = "电⼦专票开具";          //主题信息
@Test
public void ClientTestC() throws IOException, javax.mail.MessagingException {
/
/ 1:初始化默认参数
Properties props = new Properties();
props.setProperty("ansport.protocol", transportType);
props.setProperty("mail.host", emailHost);
props.setProperty("mail.user", fromUser);
props.setProperty("mail.from", fromEmail);
// 2:获取Session对象
Session session = Instance(props, null);
session.setDebug(true);
// 3:创建MimeMessage对象
MimeMessage message = new MimeMessage(session);
/
/ 4:设置发件⼈、收件⼈、主题、(内容后⾯设置)
String formName = deWord("蚂蚁⼩哥") + " <" + fromEmail + ">";
InternetAddress from = new InternetAddress(formName);
message.setFrom(from);
InternetAddress to = new InternetAddress(toEmail);
message.setRecipient(Message.RecipientType.TO, to);
//设置邮件主题
message.setSubject(subject);
//邮件发送时间
message.setSentDate(new Date());
//*****邮件内容携带附件 + (HTML内容+图⽚)使⽤Content-Type:multipart/mixed ******//
/
/ 5:设置⼀个多资源混合的邮件块设置此类型时可以同时存在附件和邮件内容  mixed代表混合
MimeMultipart mixed = new MimeMultipart("mixed");
// 5.1:创建⼀个附件资源
MimeBodyPart file_body = new MimeBodyPart();
DataHandler dhFile = new DataHandler(Resource("static/a.zip"));
file_body.setDataHandler(dhFile); //设置dhFile附件处理
file_body.setContentID("fileA");  //设置资源附件名称ID
//file_body.setFileName("拉拉.zip");  //设置中⽂附件名称(未处理编码)
file_body.deText("⼀个附件.zip"));  //设置中⽂附件名称
// 5.2:先把附件资源混合到 mixed多资源邮件模块⾥
mixed.addBodyPart(file_body);
/
/ 5.3:创建主体内容资源存储对象
MimeBodyPart content = new MimeBodyPart();
    // 把主体内容混合到资源存储对象⾥
    mixed.addBodyPart(content);
// 5.4:设置多资源内容
//=============== 构建邮件内容:多信息⽚段邮件使⽤Content-Type:multipart/related ===============//
// 5.4.1:构建⼀个多资源的邮件块⽤来把⽂本内容资源和图⽚资源合并;;;related代表多资源关联
MimeMultipart text_img_related = new MimeMultipart("related");
//text_img_related.setSubType("related");
//注:这⾥为什么填写related的请去查阅Multipart类型或者去⽂章开头跳转我之前上⼀篇邮件介绍
// 5.4.2:把关联的把多资源邮件块混合到mixed多资源邮件模块⾥
content.setContent(text_img_related);
// 5.4.3:创建图⽚资源
MimeBodyPart img_body = new MimeBodyPart();
DataHandler dhImg = new DataHandler(Resource("static/b.png"));
img_body.setDataHandler(dhImg); //设置dhImg图⽚处理
img_body.setContentID("imgA");  //设置资源图⽚名称ID
// 5.4.4:创建⽂本资源,⽂本资源并引⽤上⾯的图⽚ID(因为这两个资源我做了关联)
MimeBodyPart text_body = new MimeBodyPart();
text_body.setContent("<img src='cid:imgA' width=100/> 我是蚂蚁⼩哥!!","text/html;charset=UTF-8");
// 5.4.5:把创建出来的两个资源合并到多资源模块了
text_img_related.addBodyPart(img_body);
text_img_related.addBodyPart(text_body);
//===========================================================================================//
// 6:设置我们处理好的资源(存放到Message)
message.setContent(mixed);
// 7:保存上⾯设置的邮件内容
message.saveChanges();
// 8:获取Transport对象
Transport transport = Transport();
//9:smtp验证,就是你⽤来发邮件的邮箱⽤户名密码(若在之前的properties中指定默认值,这⾥可以不⽤再次设置)
//10:发送邮件
transport.sendMessage(message, AllRecipients()); // 发送
}
}
5:使⽤JavaMail和Thymeleaf模板发送HTML内嵌图⽚格式
  下⾯我将使⽤JavaMail通过Thymeleaf模板的⽅式发送HTML内容(HTML内容存在资源图⽚关联)+附件内容,其实这是⽅式都是通过2~4⼩节的慢慢改造,学会这种⽅式,那么我们发送公司业务上的⼀些邮件是没有太⼤压⼒的;下⾯我不在展⽰是全部代码,只把补充的代码展⽰出来,其它的参照第4节代码
  <!--导⼊thymeleaf坐标-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.12.RELEASE</version>