JAVA邮件发送详解
电子邮件
要在网络上实现邮件功能,必须有专门的邮件服务器。
这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com
电子邮件的获得需要在邮件服务器上进行申请,比如我们要使用QQ邮箱,就需要开通邮箱功能。
传输协议
SMTP协议
发送邮箱:
通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。
POP3协议
接收邮箱:
通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)
邮件收发原理
- 张三通过smtp协议连接到smtp服务器中,然后发送一封邮件给网易的邮件服务器
- 网易分析发现需要去QQ的邮件服务器,通过smtp协议将邮件转发给QQ是smtp服务器
- QQ将接收到的邮件存储在3314291346@qq.com这个邮件账号的空间中
- 李四通过pop3协议连接到pop3这个服务器收取邮件
- 从3314261346@qq.com这个邮箱中取出邮件
- pop3服务器将取出的邮件送到李四手中
【注意:】有可能收件什么的都正确的,但就是收不到邮件,可能是收件箱服务器拒绝了你发的邮件(认为是垃圾邮箱广告),这是可以在垃圾箱里找到,也可能找不到。只有更换收件箱试试。
Java发送邮件
概述
我们将用代码完成邮件的发送。这在实际项目中应用的非常广泛,比如注册需要发送邮件进行账号激活,再比如0A项目中利用邮件进行任务提醒等等。
使用Java发送E-mail十分简单,但是首先你应该准备JavaMail API和Java Activation Framework。
得到两个jar包:
- mail.jar
- activation.jar
<!-- maven 导入及其方便-->
<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>
JavaMail是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议, 如前面所讲的SMTP, POP3, IMAP,还有MIME等。 我们在使用JavaMail API编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。
我们可以先尝试发送一封简单的邮件,确保电脑可以连接网络。
- 创建包含邮件服务器的网络连接信息的Session对象。
- 创建代表邮件内容的Message对象
- 创建Transport对象, 连接服务器,发送Message,关闭连接
主要有四个核心类,我们在编写程序时,记住四个核心类,就很容易编写出Java邮件处理程序。
先来了解整个流程,在来看代码。
1.创建session对象
2.创建Transport对象
3.使用邮箱的用户名和授权码连上邮件服务器
4.创建一个Message对象(需要传递session)
message需要指明发件人、收件人以及文件内容
5.发送邮件
6.关闭连接
代码
package com.cetus.mail;
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 MailDemo01 {
public static void main(String[] args) throws Exception {
Properties prop=new Properties();
prop.setProperty("mail.host","smtp.qq.com");///设置QQ邮件服务器
prop.setProperty("mail.transport.protocol","smtp");///邮件发送协议
prop.setProperty("mail.smtp.auth","true");//需要验证用户密码
//QQ邮箱需要设置SSL加密,仅QQ邮箱才有
MailSSLSocketFactory sf=new MailSSLSocketFactory(); //此处导包注意mail类
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable","true");
prop.put("mail.smtp.ssl.socketFactory",sf);
//使用javaMail发送邮件的5个步骤
//1.创建定义整个应用程序所需要的环境信息的session对象
Session session=Session.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("XXXX@qq.com","授权码");
}
});
//开启session的debug模式,这样可以查看到程序发送Email的运行状态
session.setDebug(true);
//2.通过session得到transport对象
Transport ts=session.getTransport();
//3.使用邮箱的用户名和授权码连上邮件服务器
ts.connect("smtp.qq.com","XXXX@qq.com","授权码");
//4.创建邮件:写文件
//注意需要传递session
MimeMessage message=new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("XXXX@qq.com"));
//指明邮件的收件人
message.setRecipient(Message.RecipientType.TO,new InternetAddress("XXXX@qq.com"));
//邮件标题
message.setSubject("发送的标题");
//邮件的文本内容
message.setContent("内容","text/html;charset=UTF-8");
//5.发送邮件
ts.sendMessage(message,message.getAllRecipients());
//6.关闭连接
ts.close();
}
}
带图片和附件的代码
先认识两个类一个名词:
MIME(多用途互联网邮件扩展类型)
MimeBodyPart类
javax.mail.internet.MiBodyPart类表示的是一个MIME消息,他和MimeMessage类一样都是从Part接口继承过来。
MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。
代码: 其代码于前面一致,只是将 邮件的文本内容 修改成以下代码
图片插入:
//=================================准备图片数据
MimeBodyPart image=new MimeBodyPart();
//图片需要经过数据化的处理
DataHandler dh=new DataHandler(new FileDataSource("D:1.jpg"));
//在part中放入这个处理过图片的数据
image.setDataHandler(dh);
//给这个part设置一个ID名字
image.setContentID("bz.jpg");
//准备正文的数据
MimeBodyPart text=new MimeBodyPart();
text.setContent("这是一张正文<img src='cid:bz.jpg'>","text/html;charset=UTF-8");//cid:为上文的setContentID
//描述数据关系
MimeMultipart mm=new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related"); //此处表示发送邮件附件的类型范围
//设置到消息中,保存修改
message.setContent(mm);
message.saveChanges();
附件插入:
//=================================准备图片数据
MimeBodyPart image=new MimeBodyPart();
//图片需要经过数据化的处理
DataHandler dh=new DataHandler(new FileDataSource("D:1.jpg"));
//在part中放入这个处理过图片的数据
image.setDataHandler(dh);
//给这个part设置一个ID名字
image.setContentID("bz.jpg");
//=================================准备正文数据
MimeBodyPart text=new MimeBodyPart();
text.setContent("这是一张正文<img src='cid:bz.jpg'>","text/html;charset=UTF-8");
//=================================准备附件数据
MimeBodyPart body1= new MimeBodyPart();
body1.setDataHandler(new DataHandler(new FileDataSource("D:\\Bert\\cmd.txt")));
body1.setFileName("1.txt");
//描述数据关系
MimeMultipart mm=new MimeMultipart();
mm.addBodyPart(body1);
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("mixed"); //此处表示发送邮件附件的类型范围
//设置到消息中,保存修改
message.setContent(mm);
message.saveChanges();
接下来就可以跑起来了!!!如果你想在web页面中展示出来,也可以写成javaweb项目,需要注意的是为了满足用户体验三秒原则(这是从狂神那学的🤪),在连接邮件服务器需要花费大量的时间,和注册人数过多的情况,所以一般会使用线程来跑,点击发送则抛给用户等待消息发送的页面,连接服务器的工作任在进行。
public class Servlet extends javax.servlet.http.HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//处理前端请求
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
//将信息封装进user对象
User user = new User(username, password, email);
SendMail sendMail = new SendMail(user);
sendMail.start(); //开启线程
request.setAttribute("msg","发送成功");
try {
request.getRequestDispatcher("msg.jsp").forward(request,response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}