Java实现发送纯文本、附带图片、附件的邮件,使用JavaWeb实现邮件的发送。
Java发送邮件
传输协议
发送邮件:SMTP协议
接收邮件:POP3协议
我们通常把处理用户 smtp请求(邮件发送请求)的服务器称之为:SMTP服务器(邮件发送服务器)。
对应的,把处理用户 pop3请求的(邮件接收请求)的服务器称之为:POP3服务器(邮件接收请求)。
邮件收发原理
注意:有可能你的收件人,发件人地址等信息都填对了,控制台也打印了正确的信息,但是收件箱就是没有收到相应的邮件,有可能在【垃圾箱】中!
解决方法:重复的邮件内容不要多次发送,或者更换收件箱试试!
准备工作
QQ邮箱为例学习
首先要确保QQ邮箱开启了:POP3/SMTP服务
开启完毕后,会获得授权码,先保存下来。
新建一个 普通的Java项目。
使用Java发送E-mail十分简单,但是首先你应该准备 JavaMail API 和 Java Activation Framework。
发送邮件所需的依赖:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
纯文本邮件
发送纯文本邮件,没有上传附件、图片、音频功能。
发送邮件需要的四个核心对象!
- Session
- Transport
- Message
- Store
代码:
package com.rainszj.mail;
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 {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
// 设置QQ邮件服务器
prop.setProperty("mail.host", "smtp.qq.com");
// 邮件发送协议
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.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 收件人邮箱用户名、授权码
return new PasswordAuthentication("1315480331@qq.com", "授权码");
}
});
// 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
session.setDebug(true);
// 2、通过session得到 transport对象
Transport transport = session.getTransport();
// 3、使用邮箱的用户名和授权码连上邮件服务器
transport.connect("smtp.qq.com", "1315480331@qq.com", "授权码");
// 4、创建邮件
// 创建邮件对象,【注意需要传递 Session】
MimeMessage message = new MimeMessage(session);
// 指明邮件的发件人
message.setFrom(new InternetAddress("1315480331@qq.com"));
// 指明邮件的收件人,现在发件人和收件人是一样的
message.setRecipient(Message.RecipientType.TO, new InternetAddress("1315480331@qq.com"));
// 邮件的主题
message.setSubject("一封简单的邮件!");
// 邮件的文本内容
message.setContent("<h1 style='color: red;'>你好</h1>", "text/html;charset=utf-8");
// 5、发送邮件
transport.sendMessage(message, message.getAllRecipients());
// 6、关闭连接
transport.close();
}
}
带图片的邮件
package com.rainszj.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.util.Properties;
/**
* 发送带图片的邮件
*/
public class SendMail {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
// 设置QQ邮件服务器
prop.setProperty("mail.host", "smtp.qq.com");
// 邮件发送协议
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.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 收件人邮箱用户名、授权码
return new PasswordAuthentication("收件人的QQ邮箱", "授权码");
}
});
//==================================
// 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
session.setDebug(true);
// 2、通过session得到 transport对象
Transport transport = session.getTransport();
// 3、使用邮箱的用户名和授权码连上邮件服务器
transport.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("带图片的一封信!");
//==================================
// 准备图片数据
MimeBodyPart image = new MimeBodyPart();
// 图片需要经过数据处理 DataHandler
DataHandler dh = new DataHandler(new FileDataSource("图片的路径"));
// 在我们的Body中放入这个处理了的图片数据
image.setDataHandler(dh);
// 给图片设置一个ID,后面要用
image.setContentID("favicon.png");
// 准备正文数据
MimeBodyPart text = new MimeBodyPart();
text.setContent("这是一段带图片<img src='cid:favicon.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、发送邮件
transport.sendMessage(message, message.getAllRecipients());
// 6、关闭连接
transport.close();
}
}
cid:
通过拼装而成:
MimeMultipart 中的 subtype 默认是:mixed;
带附件的邮件
package com.rainszj.mail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
/**
* 发送邮件
*/
public class SendMail {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
// 设置QQ邮件服务器
prop.setProperty("mail.host", "smtp.qq.com");
// 邮件发送协议
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.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 收件人邮箱用户名、授权码
return new PasswordAuthentication("收件人的邮箱", "授权码");
}
});
//==================================================
// 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
session.setDebug(true);
// 2、通过session得到 transport对象
Transport transport = session.getTransport();
// 3、使用邮箱的用户名和授权码连上邮件服务器
transport.connect("smtp.qq.com", "发件人的邮箱", "授权码");
// 4、创建邮件
// 创建邮件对象,【注意需要传递 Session】
MimeMessage message = writeMail(session);
// 5、发送邮件
transport.sendMessage(message, message.getAllRecipients());
// 6、关闭连接
transport.close();
}
private static MimeMessage writeMail(Session session) throws Exception {
// 一封邮件
MimeMessage message = new MimeMessage(session);
// 指明邮件的发件人
message.setFrom(new InternetAddress("发件人的邮箱"));
// 主题
message.setSubject("带图片和附件的一封信!");
// 指明邮件的收件人,现在发件人和收件人是一样的
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的邮箱"));
/*
编写邮件内容:
1. 文本
2. 图片
3. 附件
*/
//==================================================
// 准备图片数据
MimeBodyPart image = new MimeBodyPart();
// 图片需要经过数据处理 DataHandler
DataHandler dh = new DataHandler(new FileDataSource("图片的路径"));
// 在我们的Body中放入这个处理了的图片数据
image.setDataHandler(dh);
// 给图片设置一个ID,后面要用
image.setContentID("favicon.png");
// 文本
MimeBodyPart text = new MimeBodyPart();
text.setContent("这是一段带图片<img src='cid:favicon.png'/>的正文", "text/html;charset=utf-8");
// 附件
MimeBodyPart attachment = new MimeBodyPart();
attachment.setDataHandler(new DataHandler(new FileDataSource("附件的路径")));
attachment.setFileName("hello.properties"); // 设置附件的名字
MimeBodyPart attachment2 = new MimeBodyPart();
attachment2.setDataHandler(new DataHandler(new FileDataSource("附件的路径")));
attachment2.setFileName("1.txt"); // 设置附件的名字
//==================================================
// 进行拼装
// 拼装文本和图片
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(mm,"text/html;charset=utf-8");
// 拼装附件
MimeMultipart allFile = new MimeMultipart();
allFile.addBodyPart(contentText);
allFile.addBodyPart(attachment);
allFile.addBodyPart(attachment2);
allFile.setSubType("mixed");
// 设置到消息中,保存修改
message.setContent(allFile,"text/html;charset=utf-8");
message.saveChanges();
return message;
}
}
JavaWeb实现邮件发送
新建一个JavaWeb项目
依赖
<!--javax.mail-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
注意事项:ClassNotFound,有可能是lib目录没有生成成功!
添加方法:
发送邮件的表单:
<%@ 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">
<label>用户名:</label>
<input type="text" name="username">
<br/>
<label>密码:</label>
<input type="password" name="password">
<br/>
<label>邮箱:</label>
<input type="text" name="email">
<input type="submit" value="提交">
</form>
</body>
</html>
RegisterServlet
@WebServlet("/registerServlet.do")
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
System.out.println(username);
System.out.println(password);
System.out.println(email);
User user = new User(username, password, email);
// 使用多线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况【异步任务】
SendEmail sendEmail = new SendEmail(user);
// 启动线程
sendEmail.start();
request.setAttribute("message", "注册成功,我们已经发送一封带有注册信息的邮件,请注意查收!");
request.getRequestDispatcher("info.jsp").forward(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
发送邮件的线程:
package com.rainszj.utils;
import com.rainszj.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 SendEmail extends Thread {
// 邮箱用户名
private String username = "1315480331@qq.com";
// 邮箱密码
private String pasword = "授权码";
// 发送邮件的服务器地址
private String host = "smtp.qq.com";
// 发件人的邮箱
private String from = "1315480331@qq.com";
private User user;
public SendEmail(User user) {
this.user = user;
}
@Override
public void run() {
Properties prop = new Properties();
// 设置QQ邮件服务器
prop.setProperty("mail.host", "smtp.qq.com");
// 邮件发送协议
prop.setProperty("mail.transport.protocol", "smtp");
// 需要验证用户名密码
prop.setProperty("mail.smtp.auth", "true");
//=============================================
// 关于QQ邮箱,还要设置 SSL加密,加上以下代码即可
MailSSLSocketFactory sf = null;
try {
sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//==========================================
// 1、创建定义整个应用程序所需要的的环境信息 的 Session 对象
// QQ才有,其他邮箱不用
Session session = Session.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 收件人邮箱用户名、授权码
return new PasswordAuthentication("1315480331@qq.com", "授权码");
}
});
//========================================
// 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
session.setDebug(true);
// 2、通过session得到 transport对象
Transport transport = session.getTransport();
// 3、使用邮箱的用户名和授权码连上邮件服务器
transport.connect(host, username, pasword);
// 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.getPassword() + "。请妥善保管,如有问题请联系网站客服";
message.setContent(info,"text/html;charset=utf-8");
message.saveChanges();
// 5、发送邮件
transport.sendMessage(message, message.getAllRecipients());
// 6、关闭连接
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${message}
</body>
</html>
注:在真实的开发中,我们不会这么做,通过SpringBoot可以轻易的实现邮件的发送!