邮件发送
JavaMail是SUN提供给开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发类库,支持常用的邮件协议,如SMTP、POP3、IMAP,开发人员使用JavaMail编写邮件程序时,无需考虑底层的通信细节(Socket),JavaMail也提供了能够创建出各种复杂MIME格式的邮件内容的API。
用Java实现邮件发送,需要如下两个jar做支持(博主还是提供了Maven的下载地址,点击跳转即可):
博主这里直接使用Maven的依赖:
<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>
博主这里以QQ邮件发送为例:
先开通自己QQ邮件的POP3/SMTP服务,打开QQ邮箱,然后点击如下箭头的设置:
找到如下账户的选项并选中:
找到如下的部分,开启POP3/SMTP服务,按照提示进行即可:
然后我们需要获得授权码,点击生成授权码即可,这里不出意外需要验证身份,按提示操作即可,授权码,复制出来。
然后直接上代码:
这是一个简单的邮件发送
//简单邮件:主题 + 纯文本
public void simpleMail() throws GeneralSecurityException, MessagingException {
//1、配置 以下配置都是固定值 不能随意修改
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 mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true"); //开启SSL加密支持
prop.put("mail.smtp.ssl.socketFactory", mailSSLSocketFactory);
//2、创建定义整个应用程序所需的环境信息的Session对象
//QQ才有!其他邮箱就不用,其他邮箱Session session = Session.getInstance(prop);
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名授权码
return new PasswordAuthentication("xxxx@qq.com", "xxxxx");
}
});
//开启Session的debug模式 可以在控制台查看邮件发送的运行状态
session.setDebug(true);
//3、通过session得到transport对象 邮件发送对象
Transport transport = session.getTransport();
//4、使用邮箱的用户名和授权码连上邮件服务器
transport.connect("smtp.qq.com", "xxxx@qq.com", "xxxxx");
//5、创建邮件
MimeMessage mimeMessage = new MimeMessage(session);
//设置从哪里发送
mimeMessage.setFrom(new InternetAddress("xxxx@qq.com"));
//发送到哪里去
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("yyyy@qq.com")});
//设置邮箱标题
mimeMessage.setSubject("邮件标题");
//可以发送HTML页面 收件人就会收到对应的展示内容
//mimeMessage.setContent("正文内容", "text/html;charset=UTF-8");
//纯文本内容 无格式
mimeMessage.setText("文本内容");
//6、发送邮件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
//7、关闭连接
transport.close();
}
一个较为复杂的邮件只需要将发送的消息对象(mimeMessage)再编辑即可,就第五步封装消息的时候有差异,如下:
//5、创建邮件
MimeMessage mimeMessage = new MimeMessage(session);
//设置从哪里发送
mimeMessage.setFrom(new InternetAddress("xxxx@qq.com"));
//发送到哪里去
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("yyyy@qq.com")});
//设置邮箱标题
mimeMessage.setSubject("邮件标题");
//==============================
//1.准备内嵌图片文件
//新建一个MIME的部分
MimeBodyPart image = new MimeBodyPart();
//文件处理器 获取数据源 路径可以使用绝对路径 也可以使用项目根路径 src/...
DataHandler dataHandler1 = new DataHandler(new FileDataSource("src/main/resources/1.png"));
//设置它的文件处理器
image.setDataHandler(dataHandler1);
//设置正文ID 方便正文使用
image.setContentID("1.png");
//2.准备附件部分
MimeBodyPart file2 = new MimeBodyPart();
DataHandler dataHandler2 = new DataHandler(new FileDataSource("src/main/resources/汉字.jpg"));
file2.setDataHandler(dataHandler2);
//设置文件名 作为附件传输
//MimeUtility.encodeText 用该方法加密 防止中文乱码
file2.setFileName(MimeUtility.encodeText("汉字.jpg"));
//3.准备正文内容部分
MimeBodyPart text = new MimeBodyPart();
//正文中使用设置的内嵌资源 src='cid:1.png'
text.setContent("带有图片<br/><img src='cid:1.png' /><br/>", "text/html;charset=UTF-8");
//4.将这些部分组合起来
MimeMultipart mimeMultipart = new MimeMultipart();
mimeMultipart.addBodyPart(image);
mimeMultipart.addBodyPart(file2);
mimeMultipart.addBodyPart(text);
//mixed:混合的 默认
//related:相对的
//这个可以不设置 当文件设置了正文ID 就认为是一个内嵌资源 ; 当文件设置了文件名 就认为是一个附件
//mimeMultipart.setSubType("related");
//5.设置组合内容到消息中 并保存
mimeMessage.setContent(mimeMultipart);
mimeMessage.saveChanges();
//==============================
发送之后,就会得到对应的响应结果,博主上面的代码中设置了发送日志的打印输出,我们可以通过看控制台的输出判断是否发送成功,最直接的方式就是看收件人是否收到:
上面的代码使用起来还是有点繁琐,博主自己整理了一个工具类采用配置文件的方式:
- 配置文件(mail.properties):
# 邮件服务器
mail.host=smtp.qq.com
# 邮件发送协议
mail.transport.protocol=smtp
# 邮件发送是否需要收授权
mail.smtp.auth=true
# 是否打印邮件发送信息
mail.debug=true
# 是否使用SSL安全连接 qq邮箱必须设置为true
mail.smtp.ssl.enable=true
# 邮箱名
mail.username=xxxx@qq.com
# 邮箱密码 QQ邮箱为授权码
mail.password=xxxxx
- 工具类(MailUtils.java):
package cn.ara.utils;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Properties;
/**
* QQ邮件发送简单工具类
*
* @Author Ara_Hu
* @Date 2020年3月4日15:40:29
*/
public class MailUtils {
private static String username;
private static String password;
private static Properties properties;
private static Session session;
private static Transport transport;
static {
InputStream inputStream = MailUtils.class.getClassLoader().getResourceAsStream("mail.properties");
properties = new Properties();
try {
// 1.加载配置文件
properties.load(inputStream);
username = properties.getProperty("mail.username");
password = properties.getProperty("mail.password");
MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.socketFactory", mailSSLSocketFactory);
// 2.创建定义整个应用程序所需的环境信息的Session对象
session = Session.getDefaultInstance(properties, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名授权码
return new PasswordAuthentication(username, password);
}
});
// 3.通过session得到transport对象 邮件发送对象
transport = session.getTransport();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取邮件会话
* 获取该对象就是为了设置自定义消息
*
* @return 邮件会话
*/
public static Session getSession() {
return session;
}
/**
* 自定义邮件发送
*
* @param message 自定义的消息内容
*/
public static void sendMail(MimeMessage message) throws MessagingException {
// 如果消息体中的基本参数为空 则直接抛出异常
if ((message == null) || (message.getAllRecipients() == null)) {
throw new SendFailedException();
}
// 4.使用邮箱的用户名和授权码连上邮件服务器
transport.connect(properties.getProperty("mail.host"), username, password);
// 5.邮件设置由调用者传进来 这里将发送人设置为指定的
message.setFrom(new InternetAddress(username));
// 6.发送邮件
transport.sendMessage(message, message.getAllRecipients());
// 7.关闭连接
transport.close();
}
/**
* 简单邮件发送(纯文本)
*
* @param addressee 收件人
* @param title 标题
* @param content 正文内容
* @throws GeneralSecurityException
* @throws MessagingException
*/
public static void simpleMail(String addressee, String title, String content) throws GeneralSecurityException, MessagingException {
// 4.使用邮箱的用户名和授权码连上邮件服务器
transport.connect(properties.getProperty("mail.host"), username, password);
// 5.根据用户传入的参数创建邮件
MimeMessage mimeMessage = new MimeMessage(session);
//设置从哪里发送
mimeMessage.setFrom(new InternetAddress(username));
//发送到哪里去
mimeMessage.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(addressee)});
//设置邮箱标题
mimeMessage.setSubject(title);
//纯文本内容 无格式
mimeMessage.setText(content);
// 6.发送邮件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
// 7.关闭连接
transport.close();
}
}
个人感觉封装的工具类还不错,如果有更好的封装方式,欢迎大佬前来指教。