邮件服务器
简单理解:
用户A给用户B发邮件,A把邮件发送到A所用的邮件服务器(简称a服务器),然后,a服务器确定收件人(B)的邮件服务器(b服务器),a服务器就可以将用户A的邮件发送到b服务器上,到此邮件一般发送完成了,最后用户B只要上线他的邮箱,就会查询b服务器上邮件,进而确定得到未读的邮件。
通过协议理解
用户A通过SMTP协议连接到SMTP服务器,然后发送一封邮件给网易的邮件服务器
网易分析发现,邮件的目的地是QQ的邮件服务器,就通过SMTP协议将邮件转投给QQ的SMTP服务器
QQ将接收到的邮件存储在对应收件人的邮箱帐号空间
用户B通过POP3协议连接到POP3服务器收取邮件
在用户B的帐号空间中拉取该邮件
POP3服务器将取出邮件给用户B
邮件发送的两个协议
SMTP协议
发送邮件:
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。
通过SMTP协议所指定的服务器,我们就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。
SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转你发出的电子邮件。
POP3协议
接收邮件:
POP3(Post Office Protocol 3),规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。
POP3规定:允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件。
POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。
它是因特网电子邮件的第一个离线协议标准。
Java实现邮件发送
两个重要的包
mail.jar
javax.mail
1.4.7
activation.jar
javax.activation
activation
1.1.1
1.png
发送细节
简单邮件:没有附件和图片,纯文本邮件
复杂邮件:有附件和图片
要发送邮件,需要获得协议和支持!开启服务POP3/SMTP服务
另外还可能需要获得授权码,例如qq邮箱
我们邮箱里面对应的协议开启
(QQ邮箱为例)
0.png
代码,发送简单文本
package com.vigil;
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加密,加上以下代码,其他邮箱一般不用
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对象
//QQ比较特殊的一个session初始化,要有授权码,其他邮箱一般不这样
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发送邮件的用户名、授权码
return new PasswordAuthentication("qq邮箱", "授权码");
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、通过session得到transport对象
Transport ts = session.getTransport();
//3、使用邮箱的用户名和授权码连上邮件服务器(host)
ts.connect("smtp.qq.com","qq邮箱","授权码");
//4、创建邮件
//注意需要传递session,确定要邮件发送对象等等重要信息
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("qq地址"));
//指明邮件的收件人,如果发件人和收件人是一样的,那就是自己给自己发
message.setRecipient(Message.RecipientType.TO,new InternetAddress("qq地址"));
//邮件的标题
message.setSubject("只包含文本的简单邮件");
//邮件的文本内容 和格式类型
message.setContent("你好啊!","text/html;charset=UTF-8");
//5、发送邮件,邮件和所有的收件人地址
ts.sendMessage(message,message.getAllRecipients());
//6、关闭连接
ts.close();
}
}
带图片的邮件
- MIME(多用途互联网邮件扩展类型)
MimeBodyPart类
javax.mail.internet.MimeBodePart类 表示的是一个MIME消息,他和MimeMessage类一样都是从Part接口继承过来。
MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MinmeBodypart对象。
代码
和发送简单纯文本不同地方就是第四步,创建邮件时,准备的数据不一样,用到了两个新类
//4、创建邮件
//注意需要传递session,确定要邮件发送对象等等重要信息
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("qq地址"));
//指明邮件的收件人,如果发件人和收件人是一样的,那就是自己给自己发
message.setRecipient(Message.RecipientType.TO,new InternetAddress("qq地址"));
//邮件的标题
message.setSubject("图片邮件");
//准备图片数据
MimeBodyPart image = new MimeBodyPart();
//图片需要经过数据处理。。。DataHandler;数据处理
//FileDataSource:加载图片资源
DataHandler dh = new DataHandler(new FileDataSource("D:\\javadownload\\ideaworkplace\\com.vigil\\mail-Java\\src\\t.png"));
image.setDataHandler(dh);//在body中放入这个图片处理数据
image.setContentID("test.jpg");//给图片设置一个方便后期使用的id
//准备正文数据
MimeBodyPart text = new MimeBodyPart();
text.setContent("
你好!
这是一封邮件正文带图片的邮件","text/html;charset=UTF-8");//描述数据关系
MimeMultipart mm = new MimeMultipart();//将所有MimeBodyPart封装的一个类
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");//描述数据间关系。默认值:protected String contentType = "multipart/mixed";
//设置到消息中,保存修改
message.setContent(mm);//把最后写好的封装邮件放入到消息里
message.saveChanges();//保存修改
小细节
带图片和附件的复杂邮件发送
不同之处,依旧是创建邮件的过程不一样,要准备不一样的数据
图片和附件设置数据比较接近,不过图片是设置一个ID,附件是设置一个fileName。而且都需要数据处理
//4、创建邮件
MimeMessage mimeMessage = imageMail(session);
public static MimeMessage imageMail(Session session) throws MessagingException {
//消息的固定信息
MimeMessage mimeMessage = new MimeMessage(session);
//邮件发送人
mimeMessage.setFrom(new InternetAddress("邮箱地址"));
//邮件接收人
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("邮箱地址"));
mimeMessage.setSubject("复杂邮件发送");//邮箱主体
/*
编写邮件内容
1、图片
2、邮件
3、文本
*/
//图片
//准备图片数据
MimeBodyPart body1 = new MimeBodyPart();
//图片需要经过数据处理。。。DataHandler;数据处理
//FileDataSource:加载图片资源
DataHandler dh = new DataHandler(new FileDataSource("src/t.png"));
body1.setDataHandler(dh);//在body中放入这个图片处理数据
body1.setContentID("test.jpg");//给图片设置一个方便后期使用的id
//文本
MimeBodyPart body2 = new MimeBodyPart();
body2.setContent("
你好!", "text/html;charset=UTF-8");
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("src/test.txt")));
body3.setFileName("test.txt");//设置附件名字
MimeBodyPart body4 = new MimeBodyPart();
body4.setDataHandler(new DataHandler(new FileDataSource("src/resource.properties")));
body4.setFileName("");//设置附件名字
//拼接邮件正文内容
MimeMultipart mimeMultipart1 = new MimeMultipart();
mimeMultipart1.addBodyPart(body1);
mimeMultipart1.addBodyPart(body2);
mimeMultipart1.setSubType("related");//文本和图片的之间的关系。内嵌成功
//将封装好的正文内容设为主体
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(mimeMultipart1);
//拼接附件
MimeMultipart addFile = new MimeMultipart();
addFile.addBodyPart(body3);
addFile.addBodyPart(body4);
addFile.addBodyPart(contentText);
addFile.setSubType("mixed");//正文和附件都存在邮件中,所有类型设置为mixed;
//保存到message消息中
mimeMessage.setContent(addFile);
//保存修改
mimeMessage.saveChanges();
return mimeMessage;
}
}
用户注册成功发送邮箱
邮件发送方法
package com.vigil.utils;
import com.sun.mail.util.MailSSLSocketFactory;
import com.vigil.pojo.User;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.Properties;
//多线程实现用户体验 (异步处理)
public class SendEmail extends Thread {
//用于给用户发送邮件的邮箱
private String from = "";
//邮箱用户名
private String username = "";
//邮箱的密码
private String password = "授权码";
//实现邮箱的服务器地址
private String host = "smtp.qq.com";
private User user;
public SendEmail(User user) {
this.user = user;
}
//复写run方法,在里面完成邮件发送给指定的用户
@Override
public void run() {
try {
Properties prop = new Properties();
prop.setProperty("mail.host",host); //设置为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对象
//QQ比较特殊的一个session初始化,要有授权码,其他邮箱一般不这样
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发送邮件的用户名、授权码
return new PasswordAuthentication(username, password);
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、通过session得到transport对象
Transport ts = session.getTransport();
//3、使用邮箱的用户名和授权码连上邮件服务器(host)
ts.connect(host,from,password);
//4、创建邮件
//注意需要传递session,确定要邮件发送对象等等重要信息
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress(from));
//指明邮件的收件人,如果发件人和收件人是一样的,那就是自己给自己发
message.setRecipient(Message.RecipientType.TO,new InternetAddress(user.getEmail()));
//邮件的标题
message.setSubject("用户注册邮件");
//邮件的文本内容 和格式类型
String info = "恭喜您注册成功,您的用户名: " + user.getUsername() ,+ "您的密码: " + user.getUserpassword() + "请妥善保管,如有问题请联系网站客服!!!";
message.setContent(info,"text/html;charset=UTF-8");
message.saveChanges();
//5、发送邮件,邮件和所有的收件人地址
ts.sendMessage(message,message.getAllRecipients());
//6、关闭连接
ts.close();
} catch (Exception e) {
throw new RuntimeException();
}
}
}
Servlet
package com.vigil.servlet;
import com.vigil.pojo.User;
import com.vigil.utils.SendEmail;
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 RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
//接收用户请求,封装成对象
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
User user = new User(username, password, email);
try {
//用户注册成功后,给用户发送一封邮件
//我们使用线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况
SendEmail send = new SendEmail(user);
//启动线程,线程启动之后就会执行run方法来发送邮件
send.start();
//注册用户
req.setAttribute("message","注册成功,我们已经发送一封带了注册信息的电子邮件,请注意查收");
req.getRequestDispatcher("info.jsp").forward(req,resp);
} catch (Exception e) {
e.printStackTrace();
req.setAttribute("message","注册失败!!!");
req.getRequestDispatcher("info.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
RegisterServlet
com.vigil.servlet.RegisterServlet
RegisterServlet
/RegisterServlet.do
用户实体类
package com.vigil.pojo;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String userpassword;
private String email;
public User() {
}
public User(String username, String userpassword, String email) {
this.username = username;
this.userpassword = userpassword;
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
", email='" + email + '\'' +
'}';
}
}
index页面、info页面
index
注册用户名:
密码:
邮箱:
info
Title