邮箱相关协议介绍:
参考博客:https://blog.youkuaiyun.com/suhuaiqiang_janlay/article/details/78765613
简单邮件发送案例:
import org.junit.Test;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
public class MailTest {
@Test
public void sendMail() throws Exception{
//Session的配置
Properties prop = new Properties();
prop.setProperty("mail.debug","true");//开启邮箱debug过程
prop.setProperty("mail.host", "smtp.qq.com");//邮箱域名
prop.setProperty("mail.smtp.port","25");//端口
prop.setProperty("mail.transport.protocol", "smtp");//邮箱协议
prop.setProperty("mail.smtp.auth", "true");//邮箱认证状态
//获取session
Session session = Session.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("邮箱账号","邮箱密码 是开启smtp时候的授权码");
}
});
//创建message对象
Message message = new MimeMessage(session);
//指明邮件的发件人 跟上面邮箱认证账号保持一致
message.setFrom(new InternetAddress("邮箱账号"));
//指明邮件的收件人 多个收件人逗号隔开
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("收件人"));
//邮件的标题
message.setSubject("测试发邮件标题");
//邮件的文本内容
message.setContent("邮件内容", "text/html;charset=UTF-8");
//设置信件头的发送日期
message.setSentDate(new Date());
//发送邮件 该方法内部关闭了资源,不用手动关闭了
Transport.send(message);
}
}
参考一些博客,整理写了一个MailUtil
mail.properties
# 是否开启debug调试
mail.debug=false
# 发送服务器是否需要身份验证
mail.smtp.auth=true
# 邮件发送端口
mail.smtp.port=25
# 邮件服务器主机名
mail.host=
# 发送邮件协议名称
mail.transport.protocol=smtp
# 发送邮件的昵称
mail.nick=测试昵称
# 发送邮件用户名
mail.user=
# 发送邮件邮箱密码此处是授权码
mail.pass=
# 发送邮件发件人
mail.from=
# 发送邮件收件人
mail.to=
MailConfig实体
/**
* 邮箱配置信息对象
* @author fdh
*/
public class EmailConfig {
/**是否开启debug调试*/
private String debug;
/**发送服务器是否需要身份验证*/
private String auth;
/**发送邮件端口*/
private String port;
/**邮件服务器主机名*/
private String host;
/**发送邮件协议名称*/
private String protocol;
/**发送邮件用户名*/
private String user;
/**发送邮件邮箱密码*/
private String pass;
/**发送邮件的发件人昵称*/
private String nick;
/**发送邮件发件人*/
private String from;
/**发送邮件的收件人*/
private String to;
public String getDebug() {
return debug;
}
public void setDebug(String debug) {
this.debug = debug;
}
public String getAuth() {
return auth;
}
public void setAuth(String auth) {
this.auth = auth;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
}
MailUtil
import com.dongao.core.base.EmailConfig;
import org.apache.commons.lang3.StringUtils;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import javax.mail.Message.RecipientType;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* Mail发送工具类
*
* 发件人只能从配置文件中设置
* smtp协议的方式发送邮件
*
* RecipientType类的枚举值,分别有"TO"、"CC"以及"BCC",分别代表"收件"、"抄送"以及"暗送"
*
* @author fdh
*/
public class EmailUtil {
/**创建session的配置*/
private static Properties sessionProp;
/**从配置文件中读取到的配置对象*/
private static EmailConfig email;
private static Session session;
//邮箱设置的几个相关常量
private static final String MAIL_DEBUG = "mail.debug";
private static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
private static final String MAIL_SMTP_PORT = "mail.smtp.port";
private static final String MAIL_HOST = "mail.host";
private static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
/**
* Session.getInstance();获取配置文件中读取 mail.user 和 mail.pass
* Session.getDefaultInstance();自己实现认证
*/
private static final String MAIL_USER = "mail.user";
private static final String MAIL_PASS = "mail.pass";
static {
InputStream is = EmailUtil.class.getClassLoader().getResourceAsStream("config/mail/mail.properties");
InputStreamReader isr = null;
try {
isr = new InputStreamReader(is, "UTF-8");
sessionProp = new Properties();
Properties prop = new Properties();
email = new EmailConfig();
prop.load(isr);
//设置邮箱debug模式
String debug = prop.getProperty("mail.debug");
if(StringUtils.isNotBlank(debug)){
email.setDebug(debug.trim());
}
//设置邮箱身份验证
String auth = prop.getProperty("mail.smtp.auth");
if(StringUtils.isNotBlank(auth)){
email.setAuth(auth.trim());
}
//设置邮箱发送端口
String port = prop.getProperty("mail.smtp.port");
if(StringUtils.isNotBlank(auth)){
email.setPort(port.trim());
}
//设置邮件服务器主机名
String host = prop.getProperty("mail.host");
if(StringUtils.isNotBlank(host)){
email.setHost(host.trim());
}
//设置邮件协议名称
String protocol = prop.getProperty("mail.transport.protocol");
if(StringUtils.isNotBlank(protocol)){
email.setProtocol(protocol.trim());
}
//设置邮箱的用户名
String user = prop.getProperty("mail.user");
if(StringUtils.isNotBlank(user)){
email.setUser(user.trim());
}
//设置邮箱的密码
String pass = prop.getProperty("mail.pass");
if(StringUtils.isNotBlank(pass)){
email.setPass(pass.trim());
}
//设置邮箱发件人昵称
String nick = prop.getProperty("mail.nick");
if(StringUtils.isNotBlank(nick)){
email.setNick(nick.trim());
}
//设置发送邮件的发送人
String from = prop.getProperty("mail.from");
if(StringUtils.isNotBlank(from)){
email.setFrom(from.trim());
}
//设置发送邮件的收件人
String to = prop.getProperty("mail.to");
if(StringUtils.isNotBlank(to)){
email.setTo(to.trim());
}
sessionProp.setProperty(MAIL_DEBUG,email.getDebug());
sessionProp.setProperty(MAIL_SMTP_AUTH,email.getAuth());
sessionProp.setProperty(MAIL_HOST, email.getHost());
sessionProp.setProperty(MAIL_SMTP_PORT,email.getPort());
sessionProp.setProperty(MAIL_TRANSPORT_PROTOCOL,email.getProtocol());
//sessionProp.setProperty(MAIL_USER,email.getUser());
//sessionProp.setProperty(MAIL_PASS, email.getPass());
//创建session同时认证邮箱 密码是授权码不是邮箱的密码,类比于第三方客户端登录时候用的密码
session = Session.getDefaultInstance(sessionProp, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(email.getUser(),email.getPass());
}
});
} catch (Exception e) {
throw new RuntimeException("邮箱初始化失败:",e);
}
}
/**
* 校验邮件
* (校验标题、校验内容非空性)
*
* @param subject 邮件标题
* @param content 邮件正文
* @param fileList 邮件附件
* void
*/
private static void checkEmail(String subject, String content, List<File> fileList){
if(StringUtils.isEmpty(subject)){
throw new RuntimeException("邮件标题不能为空!");
}
if(StringUtils.isEmpty(content) && (fileList==null || fileList.size()==0)){
throw new RuntimeException("邮件内容不能为空!");
}
}
/**
* 构建Message对象
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param fileList 附件
* @return 邮箱对象
* @throws Exception
*/
private static Message createMessage(String subject, String content, String to, String nick, List<File> fileList){
//校验标题正文
checkEmail(subject, content, fileList);
//邮件内容
Message msg = new MimeMessage(session);
try {
Multipart mp = createMultipart(content, fileList);
if(StringUtils.isEmpty(nick)){
msg.setFrom(new InternetAddress(email.getFrom()));
}else{
//编码解决中文乱码
String nickName = MimeUtility.encodeText(nick,"UTF-8",null);
msg.setFrom(new InternetAddress(nickName+" <"+email.getFrom()+">"));
}
msg.setSubject(subject);
msg.setRecipients(RecipientType.TO, InternetAddress.parse(to));
//Multipart加入到信件
msg.setContent(mp);
//设置信件头的发送日期
msg.setSentDate(new Date());
} catch (Exception e) {
throw new RuntimeException("构建Message对象异常",e);
}
return msg;
}
/**
* 构建附有抄送、暗送Message对象
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param cc 抄送人(多个抄送人用英文逗号隔开)
* @param bcc 暗送人(多个暗送人用英文逗号隔开)
* @param fileList 附件
* @return Message对象
*/
private static Message createMessageCcAndBcc(String subject, String content, String to, String nick, String cc, String bcc, List<File> fileList){
Message msg = createMessage(subject, content, to, nick, fileList);
try {
if(StringUtils.isNotBlank(cc)){
msg.setRecipients(RecipientType.CC, InternetAddress.parse(cc));
}
if(StringUtils.isNotBlank(bcc)){
msg.setRecipients(RecipientType.BCC, InternetAddress.parse(bcc));
}
} catch (Exception e) {
throw new RuntimeException("构建附有抄送、暗送Message对象异常:",e);
}
return msg;
}
/**
* 构建附件对象
*
* @param content 邮件正文内容
* @param fileList 附件
* @return 邮件内容对象
* Multipart
*/
private static Multipart createMultipart(String content, List<File> fileList){
//邮件内容
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = new MimeBodyPart();
try {
mbp.setContent(content, "text/html;charset=UTF-8");
mp.addBodyPart(mbp);
if(fileList!=null && fileList.size()>0){
//附件
FileDataSource fds;
for(File file : fileList){
mbp=new MimeBodyPart();
//得到数据源
fds = new FileDataSource(file);
//得到附件本身并至入BodyPart
mbp.setDataHandler(new DataHandler(fds));
//设置文件名到BodyPart
mbp.setFileName(MimeUtility.encodeText(file.getName(),"UTF-8",null));
mp.addBodyPart(mbp);
}
}
} catch (Exception e) {
throw new RuntimeException("构建附件对象异常",e);
}
return mp;
}
/**
* 通用发送邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
*/
public static void sendEmail(String subject, String content, String to, String nick, String cc, String bcc, List<File> fileList){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessageCcAndBcc(subject, content, to, nick, cc, bcc, fileList);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("通用发送邮件异常:",e);
}
}
/**
* 发送邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
*/
public static void sendEmail(String subject,String content,String to){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessage(subject, content, to, email.getNick(),null);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("发送邮件异常:",e);
}
}
/**
* 发送带有昵称的邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param nick 发件人昵称 (优先级 入参 > 配置文件)
*/
public static void sendEmailWithNick(String subject,String content,String to,String nick){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessage(subject, content, to, nick,null);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("发送带有昵称的邮件异常:",e);
}
}
/**
* 发送带有附件的邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param fileList 附件
*/
public static void sendEmailWithAttachment(String subject,String content,String to,List<File> fileList){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessage(subject, content, to,email.getNick(), fileList);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("发送带有附件的邮件异常:",e);
}
}
/**
* 发送带有抄送人的邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param cc 抄送人(多个收件人用英文逗号隔开)
* @param fileList 附件
*/
public static void sendEmailWithCc(String subject, String content, String to, String cc, List<File> fileList){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessageCcAndBcc(subject, content, to, email.getNick(), cc, null, fileList);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("发送带有昵称和附件的邮件异常:",e);
}
}
/**
* 发送带有暗送人的邮件
*
* @param subject 邮件标题
* @param content 邮件内容
* @param to 收件人(多个收件人用英文逗号隔开)
* @param bcc 暗送人(多个收件人用英文逗号隔开)
* @param fileList 附件
*/
public static void sendEmailWithBcc(String subject, String content, String to, String bcc, List<File> fileList){
if(StringUtils.isEmpty(to)){
to = email.getTo();
}
Message msg = createMessageCcAndBcc(subject, content, to, email.getNick(), null, bcc, fileList);
try {
Transport.send(msg);
} catch (MessagingException e) {
throw new RuntimeException("发送带有暗送人的邮件异常:",e);
}
}
}