一、电子邮件收发
要在网络上实现邮件功能,必须要有专门的邮件服务器。这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
SMTP服务器地址:一般是 smtp.xxx.com。比如163邮箱是 smtp.163.com,qq邮箱是smtp.qq.com。电子邮箱( E-Mail 地址) 的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能。
1、传输协议
- SMTP协议
发送邮件:我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。
- POP3协议
接收邮件:我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。
2、邮件收发原理
- 我的QQ邮箱通过 smtp 协议连接到 Smtp服务器,然后发送一封邮件给 QQ 的邮件服务器
- QQ分析发现需要去网易的邮件服务器,通过smtp协议将邮件转投给网易的 Smtp 服务器
- 网易服务器将接收到的邮件存储在 lixc56@163.com 这个邮件账号的空间中
- 我的网易邮箱通过Pop3协议连接到Pop3服务器收取邮件
- 从 lixc56@163.com 这个邮件账号的空间中取出邮件
- Pop3服务器将取出来的邮件送到我的163邮箱中
二 、Java 发送邮件
我们将用 Java 代码进行邮件的发送,Java 实现非常简单,首先你应该准备 JavaMail API 和Java Activation Framework ,得到我们需要两个 jar 包
- mail.jar
- activation.jar
在发送邮件的时候我们主要用到以下四个核心类,同时保证网络通畅。
1、纯文本邮件的发送
首先应该导入 jar 包:
邮箱中获取相应的权限
邮箱设置——>账户
获取授权码
授权码就相当于你的登录密码。
编写测试代码
package com.lxc.servlet;
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 GeneralSecurityException, MessagingException {
Properties properties = new Properties();
properties.setProperty("mail.host", "smtp.qq.com"); //设置QQ邮箱服务器
properties.setProperty("mail.transport.protocol", "smtp");//邮箱发送协议
properties.setProperty("mail.smtp.auth", "true"); //需要验证用户名密码
// 关于qq 邮箱,还需要设置SSl 加密
MailSSLSocketFactory mf = new MailSSLSocketFactory();
mf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", mf);
// java 发送邮件的五个步骤
// 1、创建整个应用程序所需的环境信息的 Session 对象
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("445505858@qq.com", "此处写你自己的授权码");
}
});
// 开启Session 的 Debug 模式,可以查看程序发送mail 的状态
session.setDebug(true);
// 2、 通过Session 对象获取transport 对象
Transport transport = session.getTransport();
// 3、使用邮箱的用户名和授权码连接上邮件服务器
transport.connect("smtp.qq.com", "445505858@qq.com", "授权码");
// 4、创建邮件的一系列操作
MimeMessage message = new MimeMessage(session);//创建邮件对象
message.setFrom(new InternetAddress("445505858@qq.com"));//指明邮件的发件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("445505858@qq.com"));//收件人
message.setSubject("纯文本");
message.setContent("java发送", "text/html;charset=utf-8");
// 5、发送邮件
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
}
2、带图片的邮件发送
发送图片前,我们需要认识以下东西:
-
MIME:多用途互联网邮件扩展类型
-
MimeBodyPart类
javax.mail.internet.MimeBodyPart类 表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。 -
MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类 Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。
编写包含内嵌图片的邮件
前面的例子中是单独的使用HTML或者是纯文本内容,但是有时候我们需要在纯文本中使用内嵌的方式显示一些图片,因此就要将纯文本和内嵌图片单独存放在 MimeBodyPart 中然后再将其存放在一个 Mimemultipart 对象中即可。代码如下:
package com.lxc.servlet;
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 PictureMail {
public static void main(String[] args) throws GeneralSecurityException, MessagingException {
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加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
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() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication("445505858@qq.com", "自己的授权码");
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、通过session得到transport对象
Transport ts = session.getTransport();
//3、使用邮箱的用户名和授权码连上邮件服务器
ts.connect("smtp.qq.com", "445505858@qq.com", "授权码");
//4、创建邮件
//创建邮件
MimeMessage message = new MimeMessage(session);
// 设置邮件的基本信息
//发件人
message.setFrom(new InternetAddress("445505858@qq.com"));
//收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("445505858@qq.com"));
//邮件标题
message.setSubject("带图片的邮件");
// 准备邮件数据
// 准备图片数据
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("src/resources/bb.png"));
image.setDataHandler(dh);
image.setContentID("bb.png");
// 准备正文数据
MimeBodyPart text = new MimeBodyPart();
text.setContent("这是一封邮件正文带图片<img src='cid:bb.png'>的邮件", "text/html;charset=UTF-8");
// 描述数据关系
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
//设置到消息中,保存修改
message.setContent(mm);
message.saveChanges();
//5.发送邮件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
}
3、带附件的邮件发送
package com.lxc.servlet;
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 FileMail {
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存在的一个特性,需要建立一个安全的链接
// 关于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("445505858@qq.com", "授权码");
}
});
//可以通过session开启Dubug模式,查看所有的过程
session.setDebug(true);
//2.获取连接对象,通过session对象获得Transport,需要捕获或者抛出异常;
Transport tp = session.getTransport();
//3.连接服务器,需要抛出异常;
tp.connect("smtp.qq.com", "445505858@qq.com", "授权码");
//4.连接上之后我们需要发送邮件;
MimeMessage mimeMessage = imageMail(session);
//5.发送邮件
tp.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
//6.关闭连接
tp.close();
}
public static MimeMessage imageMail(Session session) throws MessagingException {
//消息的固定信息
MimeMessage mimeMessage = new MimeMessage(session);
//邮件发送人
mimeMessage.setFrom(new InternetAddress("445505858@qq.com"));
//邮件接收人,可以同时发送给很多人,我们这里只发给自己;
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("445505858@qq.com"));
mimeMessage.setSubject("我也不知道是个什么东西就发给你了"); //邮件主题
/*
编写邮件内容
1.图片
2.附件
3.文本
*/
//图片
MimeBodyPart body1 = new MimeBodyPart();
body1.setDataHandler(new DataHandler(new FileDataSource("src/resources/bb.png")));
body1.setContentID("bb.png"); //图片设置ID
//文本
MimeBodyPart body2 = new MimeBodyPart();
body2.setContent("请注意,我不是广告<img src='cid:bb.png'>", "text/html;charset=utf-8");
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("src/resources/1.txt")));//路径
body3.setFileName("1.txt"); //附件设置名字
//拼装邮件正文内容
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;
}
}
4、JavaWeb 发送邮件
现在很多网站都会在用户注册成功之后给用户发送一封邮件,邮件包括我们一些信息等。那么这个功能就要借助 JavaMail 来实现了。下面让我们写一个用户注册成功之后系统发送一封邮件给用户的案例。
- 新建一个 JavaWeb 项目,配置 TomCat ,添加 jar 包
- 编写用户实体类
package com.lxc.pojo;
public class User {
private String name;
private String pwd;
private String email;
public User(String name, String pwd, String email) {
this.name = name;
this.pwd = pwd;
this.email = email;
}
public User() {
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", pwd='" + pwd + '\'' +
", email='" + email + '\'' +
'}';
}
}
- 前端注册页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/mail" method="post">
用户名:<input type="text" name="name"><br/>
密码:<input type="password" name="pwd"><br/>
邮箱:<input type="text" name="email"><br/>
<input type="submit" value="注册">
</form>
</body>
</html>
- 邮件发送工具类
package com.lxc.utils;
import com.lxc.pojo.User;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class Sendmail extends Thread {
//用于给用户发送邮件的邮箱
private String from = "445505858@qq.com";
//发送邮件的服务器地址
private String host = "smtp.qq.com";
//邮箱的密码
private String password = "你自己的授权码";
private User user;
//邮箱的用户名
private String username = "445505858@qq.com";
public Sendmail(User user) {
this.user = user;
}
//重写run方法的实现,在run方法中发送邮件给指定的用户
@Override
public void run() {
try {
Properties prop = new Properties();
prop.setProperty("mail.host", host);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//1、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication("445505858@qq.com", "你自己的授权码");
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、通过session得到transport对象
Transport ts = session.getTransport();
//3、使用邮箱的用户名和授权码连上邮件服务器
ts.connect(host, username, password);
//4、创建邮件
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from)); //发件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); //收件人
message.setSubject("用户注册邮件"); //邮件的标题
String info = "恭喜您注册成功,您的用户名:" + user.getName() + ",您的密码:" + user.getPwd() + ",请妥善保管,如有问题请联系网站客服!!";
message.setContent(info, "text/html;charset=UTF-8");
message.saveChanges();
//发送邮件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
- 编写对应是 Servlet
package com.lxc.servlet;
import com.lxc.pojo.User;
import com.lxc.utils.Sendmail;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MailServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//接收用户请求,封装成对象
String username = request.getParameter("name");
String password = request.getParameter("pwd");
String email = request.getParameter("email");
User user = new User(username,password,email);
//用户注册成功之后,给用户发送一封邮件
//我们使用线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况;
Sendmail send = new Sendmail(user);
//启动线程,线程启动之后就会执行run方法来发送邮件
send.start();
//注册用户
request.setAttribute("message", "注册成功,我们已经发了一封带了注册信息的电子邮件,请查收!如网络不稳定,可能过会儿才能收到!!");
request.getRequestDispatcher("info.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message", "注册失败!!");
request.getRequestDispatcher("info.jsp").forward(request, response);
}
}
}
- 配置 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>MailServlet</servlet-name>
<servlet-class>com.lxc.servlet.MailServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MailServlet</servlet-name>
<url-pattern>/mail.do</url-pattern>
</servlet-mapping>
</web-app>
- 发送成功或失败的页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>提示信息</title>
</head>
<body>
${message}
</body>
</html>
运行 TomCat 进行测试