以qq邮箱为例
邮件收发
要在网络上实现邮件功能,必须要有专门的邮件服务器
邮件服务器类似于现实中的邮局,主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
1.张三通过SMTP协议连接到SMTP服务器,然后发送一封邮件给网易的邮件服务器;
2.网易分析发现需要去qq的邮件服务器,通过SMTP协议将邮件转投给qq的SMTP服务器
3.qq将接收到的邮件存储在李四的邮件账号的空间中
4.李四通过pop3协议连接到pop3服务器收取邮件
5.从李四的这个邮件账号的空间中取出邮件
6.Pop3服务器将取出来的邮件送到李四手中
注意:有可能你收件人地址,发件人地址等信息都正确了,控制台也打印了正确的信息,但是在收件箱就是收不到信息。这很可能是收件箱服务器拒收了你发的邮件(比如认为你的邮件是广告),这时可能在垃圾箱中能找到,可能找不到。解决办法是重复的邮件内容不要多次发送,或者更换收件箱
1. 给QQ邮箱发邮件
1.1 导包
使用Java发送Email需要准备JavaMail API和Java Activation Framework得到两个jar包mail.jar和activation.jar
这个包一定不要导错了,否则后续会出现QQ设置SSL加密错误
<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>
1.2 在邮箱中配置
我们要打开QQ邮箱的设置
将第一个开启。一般都需要密保验证
将验证码自己保存下来
1.3 MailDemo01
package com.hxl;
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邮箱需要设置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.getDefaultInstance(prop, new Authenticator() {
public 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("发送的标题");
//邮件的文本内容
//内容还可以添加样式等等比如说价格<h1 style='color:red'></h1>
message.setContent("内容","text/html;charset=UTF-8");
//5.发送邮件
ts.sendMessage(message,message.getAllRecipients());
//6.关闭连接
ts.close();
}
}
1.4 运行查看结果
没有网络,验证码不对等都会出现错误。
2. 发送复杂内容
MIME(多用途互联网邮件扩展类型)
MimeBodyPart类:javax.mail.internet.MimeBodyPart类表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来的
MimeMultipart类:javax.mail.internet.MimeMultipart是抽象类Multipart的实现子类,它用来组合多个MIME消息,一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。
2.1 图片地址
右键找到我们需要的图片地址
2.2 发送带图片的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 MailDemo02 {
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邮箱需要设置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.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication("xxxxx@qq.com","授权码");
}
});
//开启session的debug模式,这样可以查看到程序发送Email的运行状态
session.setDebug(true);
//2.通过session得到transport对象
Transport ts=session.getTransport();
//3.使用邮箱的用户名和授权码连上邮件服务器
ts.connect("smtp.qq.com","xxxxx@qq.com","授权码");
//4.创建邮件:写文件
//注意需要传递session
MimeMessage message=new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("xxxxx@qq.com"));
//指明邮件的收件人
message.setRecipient(Message.RecipientType.TO,new InternetAddress("xxxxx@qq.com"));
//邮件标题
message.setSubject("带着图片");
//邮件的文本内容
//=================================准备图片数据=======================================
MimeBodyPart image=new MimeBodyPart();
//图片需要经过数据化的处理 DataHandler数据处理
//修改成自己的图片地址
DataHandler dh=new DataHandler(new FileDataSource("D:\\aAAAA\\util\\FunctionExtensio\\mail-java\\src\\main\\resources\\1.jpg"));
//在MimeBodyPart中放入这个处理过图片的数据
image.setDataHandler(dh);
//给这个图片设置一个ID名字,在后面可以使用
image.setContentID("bz.jpg");
//准备正文的数据
MimeBodyPart text=new MimeBodyPart();
//这里的cid就是 上面的setContentID
text.setContent("这是一封正文带着图片<img src='cid:bz.jpg'>","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());
//6.关闭连接
ts.close();
}
}
2.3 测试结果
3. 发送带文件的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 MailDemo03 {
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("xxxxxxx@qq.com", "授权码");
}
});
//可以通过session开启Dubug模式,查看所有的过程
session.setDebug(true);
//2.获取连接对象,通过session对象获得Transport,需要捕获或者抛出异常;
Transport tp = session.getTransport();
//3.连接服务器,需要抛出异常;
tp.connect("smtp.qq.com","xxxxxxx@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("xxxxx@qq.com"));
//邮件接收人,可以同时发送给很多人,我们这里只发给自己;
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("xxxxxx@qq.com"));
mimeMessage.setSubject("带文件的"); //邮件主题
/*
编写邮件内容
1.图片
2.附件
3.文本
*/
//图片
MimeBodyPart body1 = new MimeBodyPart();
body1.setDataHandler(new DataHandler(new FileDataSource("D:\\aAAAA\\util\\FunctionExtensio\\mail-java\\src\\main\\resources\\1.jpg")));
body1.setContentID("bz.jpg"); //图片设置ID
//文本
MimeBodyPart body2 = new MimeBodyPart();
body2.setContent("请注意,我不是广告<img src='cid:bz.jpg'>","text/html;charset=utf-8");
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("src/resources/log4j.properties")));
body3.setFileName("log4j.properties"); //附件设置名字
MimeBodyPart body4 = new MimeBodyPart();
body4.setDataHandler(new DataHandler(new FileDataSource("src/resources/1.txt")));
body4.setFileName(""); //附件设置名字
//拼装邮件正文内容
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(body4); //附件
allFile.addBodyPart(contentText);//正文
allFile.setSubType("mixed"); //正文和附件都存在邮件中,所有类型设置为mixed;
//放到Message消息中
mimeMessage.setContent(allFile);
mimeMessage.saveChanges();//保存修改
return mimeMessage;
}
}
4. JavaWeb发送邮件
现在很多的网站都提供有用户注册功能, 通常我们注册成功之后就会收到一封来自注册网站的邮件。邮件里面的内容可能包含了我们的注册的用户名和密码以及一个激活账户的超链接等信息。今天我们也来实现一个这样的功能,用户注册成功之后,就将用户的注册信息以Email的形式发送到用户的注册邮箱当中,实现发送邮件功能就得借助于JavaMail了。
导包的时候一定要注意导入正确的,
4.1 项目准备
新建一个Javaweb项目,配置好Tomcat,添加jar包
<dependencies>
<!--Servlet 依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--JSP依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
4.2 前端页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<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>
info.jsp(提示信息)
<<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>提示信息</title>
</head>
<body>
${message}
</body>
</html>
4.3 User实体类
package com.hxl.pojo;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
private String email;
public User() {
}
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
4.4 Servlet
package com.hxl.servlet;
import com.hxl.pojo.User;
import com.hxl.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 RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//接收用户请求,封装成对象
String username = request.getParameter("username");
String password = request.getParameter("password");
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);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
4.5 注册servlet
<servlet>
<servlet-name>RegisterServlet</servlet-name>
<servlet-class>com.hxl.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterServlet</servlet-name>
<url-pattern>/RegisterServlet.do</url-pattern>
</servlet-mapping>
4.6 utils工具类
package com.hxl.utils;
import com.sun.mail.util.MailSSLSocketFactory;
import com.hxl.pojo.User;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
//网站3秒原则:用户体验
//多线程实现用户体验!! (异步处理)
public class Sendmail extends Thread{
//用于给用户发送邮件的邮箱
private String from = "xxxx@qq.com";
//邮箱的用户名
private String username = "xxxx@qq.com";
//邮箱的密码
private String password = "授权码";
//发送邮件的服务器地址
private String host = "smtp.qq.com";
private User user;
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("xxxx@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.getUsername() + ",您的密码:" + user.getPassword() + ",请妥善保管,如有问题请联系网站客服!!";
message.setContent(info, "text/html;charset=UTF-8");
message.saveChanges();
//发送邮件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.7 有可能报错这个问题:
这个是由于jar包没导进去。首先我们去看一下Project Structure中查看Artifacts选中自己的module查看jar包。还有可能是Tomcat中没有这两个包,我们需要把这两个包复制到tomcat文件夹中
4.8 测试结果
5. 在springboot中实现
@Autowired
JavaMailSenderImpl mailSender;
@Test
Public void contextLoads(){
SimpleMailMessage message = new SimpleMailMessage();
message.setSubjext("主题");
message.setText("文本");
message.setFrom("从哪里来的邮箱");
message.setTo("去那里的邮箱");
mailSender.send(message);
}
@Test
Public void contextLoads2() throws Exception{
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true)
helper.setSubjext("主题");
helper.setText("<h1>文本</h1>",true);
//附件
helper.addAttachment("1.jpg",new File(""));
helper.setFrom("从哪里来的邮箱");
helper.setTo("去那里的邮箱");
mailSender.send(helper);
}
在application.properties中进行配置
spring.mail.username=xxxxx@qq.com
spring.mail.password=授权码
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true