电子邮件
要在网络上实现邮件功能,必须要有专门的邮件服务器
- 邮件服务器作用:
- 负责接受用户投递过来的邮件
- 将邮件投递到邮件接收者的电子邮箱
邮件协议
- 发送邮件:SMTP协议
通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)
SMTP服务器地址:一般是smtp.xxx.com,比如163邮箱是smtp.163.com、qq邮箱是 smtp.qq.com- 接受邮件: POP3协议
通常把处理用户pop3请求(邮件接受请求)的服务器称之为POP3服务器(邮件接受服务器)
电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请
邮件传递过程
- 情景:A使用网易邮箱向B的QQ邮箱发送一封邮件
- A通过smtp协议连接到smtp服务器,然后发送一封邮件给网易的邮件服务器
- 网易分析发现该邮件是发往QQ的邮件服务器的,通过smtp协议将邮件转投给QQ的smtp服务器
- QQ将接受到的邮件储存在xxx@qq.com 这个账号中
- B通过pop3协议连接到pop3协议连接到pop3服务器收取邮件
- 从xxx@qq.com 这个邮件账号的空间中取出邮件
- pop3 服务器将取出来的邮件发送到B
- 注意:如果请求过程正确,但是收件箱始终接受不到信息,可能就是收件箱服务器拒收了你发的邮件
通过Java发送邮件
发送邮件需要获得协议和支持!开启服务POP3/PMTP服务
- 准备 JavaMail API 和 Java Activation Framework.
得到两个jar包:
- mail.jar
- activation.jar
- JavaMail是sun公司为方便Java开发人员在应用程序中实现邮件发送和接受功能提供而提供的一套标准开发包,他支持一些常用的邮件协议,如SMTP、POP3、IMAP以及MIME等。当我们在实现JavaMail开发包中相应的API类即可;
通过Java发送邮件流程
- 创建包含邮件服务器的网络连接信息的Session对象
- 创建代表邮件内容的Message对象
- 创建Transport对象,连接服务器,发送Message,关闭连接
使用JavaMail发送邮件的5个步骤
- 创建定义整个应用程序所需的环境信息的Session对象
- 通过session得到transport对象
- 使用邮箱的用户名和授权码连上邮件服务器
- 创建邮件
- 发送邮件
- 关闭连接
JavaMail发送简单邮件(纯文本,无附件)
- MailDemo.java
package com.nadoutong.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 MailDemo {
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加密,以下4行
MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable","true");
properties.put("mail.smtp.ssl.socketFactory",mailSSLSocketFactory);
//todo 1.创建定义整个应用程序所需的环境信息Session对象,也是qq独有的
Session session=Session.getDefaultInstance(properties, new Authenticator() {
@Override
//发送邮件用户名、授权码
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xxxxxx@qq.com","授权码");
}
});
//todo 开启Session 的debug 模式,可以查看程序发送Email 的运行状态
session.setDebug(true);
//todo 2.通过session 得到transport对象
Transport transport = session.getTransport();
// todo 3.使用邮箱的用户名和授权码连上邮件服务器
transport.connect("smtp.qq.com","xxxxxx@qq.com","授权码");
//todo 4.创建邮件
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("xxxxxx@qq.com"));
//指明邮件的收件人
message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("xxxxxx@qq.com")});
//邮件的标题
message.setSubject("java 发送的邮件");
//邮件的文本内容
message.setContent("<h1>欢迎使用java发送邮件</h1>","text/html;charset=UTF-8");
//todo 5.发送邮件
transport.sendMessage(message,message.getAllRecipients());
//todo 6.关闭连接
transport.close();
}
}
JavaMail发送复杂邮件(有附件)
MIME (多用途互联网邮件扩展类型)
- MimeBodyPart类
javax.mail.internet.MimeBodyPart 类 表示一个MIME消息,他和MimeMessag 类一样,都是从Part接口继承过来。
- MimeMultipart类
javax.mail.internet.MimeMultipart 是抽象类 Multipart 的实现子类,他用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。
- MailDemo2.java
package com.nadoutong.Mail;
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 MailDemo2 {
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加密,以下4行
MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable","true");
properties.put("mail.smtp.ssl.socketFactory",mailSSLSocketFactory);
//todo 1.创建定义整个应用程序所需的环境信息Session对象,也是qq独有的
Session session=Session.getDefaultInstance(properties, new Authenticator() {
@Override
//发送邮件用户名、授权码
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xxxxxx@qq.com","gbqemiiwajrpbhbh");
}
});
//todo 开启Session 的debug 模式,可以查看程序发送Email 的运行状态
session.setDebug(true);
//todo 2.通过session 得到transport对象
Transport transport = session.getTransport();
// todo 3.使用邮箱的用户名和授权码连上邮件服务器
transport.connect("smtp.qq.com","xxxxxxx@qq.com","gbqemiiwajrpbhbh");
//todo 4.创建邮件
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("xxxxxxx@qq.com"));
//指明邮件的收件人
message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("xxxxxxx@qq.com")});
//邮件的标题
message.setSubject("java 发送的邮件");
//邮件的文本内容
message.setContent("<h1>欢迎使用java发送邮件</h1>","text/html;charset=UTF-8");
//===========================================
//准备添加图片
MimeBodyPart image = new MimeBodyPart();
//图片需要进过数据处理 DataHandler:数据处理
DataHandler dataHandler = new DataHandler(new FileDataSource("C:\\Users\\admin\\Pictures\\cx\\unity.png"));
//将处理过后的图片放入MimeBodyPart
image.setDataHandler(dataHandler);
//给图片设置一个ID
image.setContentID("unity.png");
//准备正文数据
MimeBodyPart text = new MimeBodyPart();
text.setContent("这是一封邮件正文带图片<image src='cid:unity.png'>的邮件","text/html;charset=UTF-8");
//准备附件
MimeBodyPart bodys = new MimeBodyPart();
bodys.setDataHandler(new DataHandler(new FileDataSource("E:\\java代码\\JAVA_WEB\\CEX_DEMO\\START_JAVAWEB\\src\\main\\webapp\\resources\\test.properties")));
//设置附件的名字
bodys.setFileName("test.properties");
//描述数据关系
MimeMultipart mimeMultipart = new MimeMultipart();
mimeMultipart.addBodyPart(text);
mimeMultipart.addBodyPart(image);
//文件和图片内嵌成功
mimeMultipart.setSubType("related");
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(mimeMultipart);
// 拼接附件
MimeMultipart allFile = new MimeMultipart();
allFile.addBodyPart(bodys);
allFile.addBodyPart(contentText);
allFile.setSubType("mixed");
//设置到消息中,保存
message.setContent(allFile);
message.saveChanges();
//todo 5.发送邮件
transport.sendMessage(message,message.getAllRecipients());
//todo 6.关闭连接
transport.close();
}
}
java web 发送邮件
一般网站都提供用户注册功能,通常我们注册成功之后就会收到一封来自注册网站的邮件,实现发送邮件功能就借助于JavaMail了
- info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>${msg}</p>
</body>
</html>
- register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/RegisterServlet.do" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
邮箱:<input type="text" name="email"><br/>
<input type="submit" value="注册">
</form>
</body>
</html>
- web.xml
<servlet>
<servlet-name>RegisterServlet</servlet-name>
<servlet-class>com.nadoutong.Servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterServlet</servlet-name>
<url-pattern>/RegisterServlet.do</url-pattern>
</servlet-mapping>
- User.java
- 网络中传输的都要进行序列化
package com.nadoutong.Servlet.pojo;
import java.io.Serializable;
import java.util.Objects;
//网络中传输的 都需要进行序列化
public class User implements Serializable {
private String username;
private String age;
private String email;
private String password;
public User(String username, String email, String password) {
this.username = username;
this.email = email;
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(username, user.username) && Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(username, age);
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age='" + age + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
}
- Sendmail.java
package com.nadoutong.threads;
import com.nadoutong.Servlet.pojo.User;
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 extends Thread{
//用于给用户发送邮件的邮箱
private String from="xxxxx@qq.com";
//邮箱的用户名
private String username="xxxxx@qq.com";
//邮箱的密码
private String password ="gbqemiiwajrpbhbh";
//发送邮件的服务器地址
private String host="smtp.qq.com";
private User user;
public Sendmail(User user){
System.out.println("进入了Sendmail");
this.user=user;
}
public Sendmail(){
}
//重写run方法,在run方法中发送邮件给指定的用户
@Override
public void run() {
System.out.println("进入了Sendmail run()");
try {
Properties properties = new Properties();
properties.setProperty("mail.host",host);//设置qq邮件服务器
properties.setProperty("mail.transport.protocol","smtp");//邮件发送协议
properties.setProperty("mail.smtp.auth","true");//需要验证用户名密码
//qq邮箱,还要设置SSL加密,以下4行
MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable","true");
properties.put("mail.smtp.ssl.socketFactory",mailSSLSocketFactory);
//todo 1.创建定义整个应用程序所需的环境信息Session对象,也是qq独有的
Session session=Session.getDefaultInstance(properties, new Authenticator() {
@Override
//发送邮件用户名、授权码
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xxxxx@qq.com","gbqemiiwajrpbhbh");
}
});
//todo 开启Session 的debug 模式,可以查看程序发送Email 的运行状态
session.setDebug(true);
//todo 2.通过session 得到transport对象
Transport transport = session.getTransport();
// todo 3.使用邮箱的用户名和授权码连上邮件服务器
transport.connect(host,username,password);
//todo 4.创建邮件
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress(from));
//指明邮件的收件人
message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(user.getEmail())});
//邮件的标题
message.setSubject("java 发送的邮件");
//邮件的文本内容
String info="恭喜您以成功注册,您的用户名:"+user.getUsername()+",您的密码:"+user.getPassword()+",请妥善保管";
message.setContent(info,"text/html;charset=UTF-8");
message.saveChanges();
//todo 5.发送邮件
transport.sendMessage(message,message.getAllRecipients());
//todo 6.关闭连接
transport.close();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- RegisterServlet .java
package com.nadoutong.Servlet;
import com.nadoutong.Servlet.pojo.User;
import com.nadoutong.threads.Sendmail;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Handler;
/**
* 网站3秒原则 :用户体验
* 多线程来解决(异步处理)
*/
public class RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接受请求,并封装成对象
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
User user = new User(username,email,password);
System.out.println(user.toString());
//使用线程来专门发送邮件,防止出现耗时操作
Sendmail sendmail = new Sendmail(user);
//启动线程
sendmail.start();
//注册成功返回
req.setAttribute("msg","注册成功,我们已经发出一份电子邮件,请注意查收");
req.getRequestDispatcher("info.jsp").forward(req,resp);
}
}
因为是通过多线程的,当邮件还在发送的时候就可以跳转到相应页面