1、引入依赖
java发送电子邮件依赖两个jar包
mail.jar 1.4.5
activation.jar
一下是Maven引用,非Maven项目从网上下载jar后导入
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
2、准备工作
2.1、创建文本类型类TextType.java
/**
* 文本类型
* @Title: TextType.java
* @Package cn.currant.enums
* @Description: TODO
* @author Autumn、
* @date 2018年6月19日
*/
public class TextType {
/**
* 超文本标记语言文本 .html
*/
public final static String HTML = "text/html";
/**
* 普通文本 .txt
*/
public final static String TXT = "text/plain";
/**
* RTF文本
*/
public final static String RTF = "application/rtf";
/**
* GIF图形 .gif
*/
public final static String GIF = "image/gif";
/**
* JPEG图形 .jpeg,.jpg
*/
public final static String JPEG = "image/jpeg";
/**
* au声音文件.au
*/
public final static String AU = "audio/basic";
/**
* AVI文件 .avi
*/
public final static String AVI = "video/x-msvideo";
/**
* GZIP文件 .gz
*/
public final static String GZ = "image/gif";
/**
* TAR文件 .tar
*/
public final static String TAR = "application/x-gzip";
}
2.2、创建字符集类Charset.java
/**
* 字符编码方式
* @Title: Charset.java
* @Package cn.currant.enums
* @Description: TODO
* @author Autumn、
* @date 2018年6月19日
*/
public class Charset {
/**
* ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126
* 是打印字符,可以通过键盘输入并且能够显示出来。
*/
public final static String ASCII = "ASCII";
/**
* ISO 组织在 ASCII 码基础上又制定了一些列标准用来扩展 ASCII 编码,它们是 ISO-8859-1~ISO-8859-15,其中
* ISO-8859-1 涵盖了大多数西欧语言字符,是单字节编码,它总共能表示 256 个字符。
*/
public final static String ISO88591 = "ISO-8859-1";
/**
* GB2312 双字节编码,总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,包含
* 6763 个汉字。
*/
public final static String GB2312 = "GB2312";
/**
* GBK 扩展 GB2312,加入更多的汉字,它的编码范围是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能表示 21003
* 个汉字,它的编码是和 GB2312 兼容的,用 GB2312 编码的汉字可以用 GBK 来解码,并且不会有乱码。
*/
public final static String GBK = "GBK";
/**
* GB18030 我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与 GB2312
* 编码兼容,这个虽然是国家标准,但是实际应用系统中使用的并不广泛。
*/
public final static String GB18030 = "GB18030";
/**
* UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以是由 1~6 个字节组成。
*/
public final static String UTF8 = "UTF-8";
/**
* UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示
*/
public final static String UTF16 = "UTF-16";
}
2.3、创建配置文件email.properties
#邮箱的配置文件(根据自己的邮箱账号和授权码以及host进行配置)
#邮箱服务器hosp
EMAIL.DEFAULT.HOST=smtp.163.com
#邮箱账号
EMAIL.DEFAULT.USERNAME=********
#邮箱授权码
EMAIL.DEFAULT.PASSWORD=********
#发送到哪个邮箱,如果是发送到用户的邮箱可以不用配置这个
EMAIL.ADDRESSEESTO=*********@qq.com
3、创建邮件实体类MyEmail.java(相当于一封信)
import java.io.File;
import java.security.GeneralSecurityException;
import java.util.Map;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
/**
* 邮件实体类
*
* @Title: MyEmail.java
* @Package cn.currant.utils.mail
* @Description: TODO
* @author Autumn、
* @date 2018年12月16日
*/
public class MyEmail {
/**
* 邮件主体
*/
private MimeMessage message = null;
/**
* 主机host
*/
private String host = null;
/**
* 用户名
*/
private String username = null;
/**
* @param host
* 主机host
* @param username
* 用户名
* @param password
* 授权码
* @throws MessagingException
* @throws GeneralSecurityException
*/
public MyEmail(String host, final String username, final String password)
throws MessagingException, GeneralSecurityException {
this.host = host;
this.username = username;
Properties prop = new Properties();
prop.setProperty("mail.host", host);// 指定主机
prop.setProperty("mail.smtp.auth", "true");// 指定验证为true
// 创建验证器
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
};
// 获取session对象
Session session = Session.getInstance(prop, auth);
message = new MimeMessage(session);
}
/**
* @param from
* 发件人昵称,为null表示不使用昵称
* @param addresseesTO
* 收件人 (多个用英文逗号隔开),必须填
* @param addresseesCC
* 抄送 没有就传空(多个用英文逗号隔开)
* @param addresseesBCC
* 暗送 没有就传空(多个用英文逗号隔开)
* @param subject
* 标题 必须赋值
* @param content
* 正文 必须赋值
* @param files
* 多个文件 没有就传空
* @return
*/
public MyEmail getMail(String from, String addresseesTO, String addresseesCC, String addresseesBCC, String subject,
String content, String textType, String charset, Map<String, File> files) {
String fromDefault = username + "@" + host.substring(5, host.lastIndexOf(".")) + ".com";
try {
// 设置发件人
if (from == null || from.equals("")) {
message.setFrom(new InternetAddress(fromDefault));
} else {
message.setFrom(new InternetAddress(fromDefault, from, charset));
}
// 设置收件人
if (addresseesTO != null && !addresseesTO.equals("")) {
message.setRecipients(RecipientType.TO, addresseesTO);
} else {
message.setRecipients(RecipientType.TO, EmailUtils.getAddresseesTO());
}
// 设置抄送人
if (addresseesCC != null && !addresseesCC.equals("")) {
message.setRecipients(RecipientType.CC, addresseesCC + "," + fromDefault);
} else {
// message.setRecipients(RecipientType.CC, fromDefault);
}
// 设置暗送人
if (addresseesBCC != null && !addresseesBCC.equals("")) {
message.setRecipients(RecipientType.BCC, addresseesBCC);
}
// 设置标题
if (subject != null && !subject.equals("")) {
message.setSubject(subject);
}
// 包含附件文件的邮件
if (files != null) {
MimeMultipart multipart = new MimeMultipart();
MimeBodyPart contentPart = new MimeBodyPart();
contentPart.setContent(content, textType + ";charset=" + charset);
multipart.addBodyPart(contentPart);
for (Map.Entry<String, File> entry : files.entrySet()) {
MimeBodyPart part = new MimeBodyPart();
part.attachFile(entry.getValue());
part.setFileName(MimeUtility.encodeText(entry.getKey()));
multipart.addBodyPart(part);
}
message.setContent(multipart);
} else {
// 无附件邮件
if (content != null && !content.equals(""))
message.setContent(content, textType.toString() + ";charset=" + charset);
}
return this;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 发送邮件
*
* @return 返回true表示成功发送
*/
public boolean send() {
try {
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return true;
}
}
4.创建邮件工具类EmailUtils.java
package com.template.utils.mail;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.template.utils.common.UntilEmpty;
/**
* 邮件发送工具
* 使用前必须导入两个依赖jar包 activation.jar mail.jar
* 大部分邮箱都有拦截垃圾邮件的功能,发送的邮件容易被自己邮箱的邮箱服务器和对方邮箱的邮箱服务器拦截。
* 在发送的时候给自己抄送一份可以防止被自己邮箱的邮箱服务器拦截出现554错误,注意发送的文本内容,防止被对方邮箱的邮箱服务器拦截。
* 邮箱的POP3/SMTP服务需要自己登陆邮箱手动开启,开启后用授权码当做密码使用。 示例代码:
* @Title: EmailUtils.java
* @Package com.template.utils.mail
* @Description: TODO
* @author Autumn、
* @date 2017年12月16日
* EmailUtils .getEmail("smtp.163.com", "**********", "********", true) .getMail( "某宝网", "*******@qq.com",
* null, null, "某宝网系统邮件", "<div style='width: 100px;height: 100px;background-color: red;'></div>",
* TextType.HTML, Charset.UTF8, files).send();
*/
@Component
public class EmailUtils {
/**
* 默认的邮箱host
*/
private static String defaultHost;
/**
* 默认的邮箱用户名
*/
private static String defaultUsername;
/**
* 默认的授权码(发送的邮箱要开启POP3/SMTP服务拿到授权码)
*/
private static String defaultPassword;
/**
* 默认发送邮箱
*/
private static String addresseesTO;
/**
* 使用这个方法获得邮件实例后,发送的邮件将以这个账号发送。
*
* @param defaultHost
* 主机host
* @param defaultUsername
* 用户名 /@符号前的一串
* @param defaultPassword
* 授权码(发送的邮箱要开启POP3/SMTP服务拿到授权码)
* @param setDefault
* true表示设置成默认账号,之后默认用这个账号发送,false表示不设置成默认
* @return 邮件实例
*/
public static MyEmail getEmail(String host, String username, String password, boolean setDefault) {
if (setDefault) {
defaultHost = host;
defaultUsername = username;
defaultPassword = password;
}
try {
return new MyEmail(host, username, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 使用默认参数获取Email对象,获取时只配置主机 相当于获取一个贴有邮票的信封,调用getMail设置内容和发送人
*
* @return
*/
public static MyEmail getEmail() {
if (UntilEmpty.isNullorEmpty(defaultHost) || UntilEmpty.isNullorEmpty(defaultUsername)
|| UntilEmpty.isNullorEmpty(defaultPassword))
System.out.println("主机或发送账号及授权码未配置!");
try {
return new MyEmail(defaultHost, defaultUsername, defaultPassword);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @return the defaultHost
*/
public static String getDefaultHost() {
return defaultHost;
}
/**
* @param defaultHost
* the defaultHost to set
*/
@Value("${EMAIL.DEFAULT.HOST}")
public void setDefaultHost(String defaultHost) {
EmailUtils.defaultHost = defaultHost;
}
/**
* @return the defaultUsername
*/
public static String getDefaultUsername() {
return defaultUsername;
}
/**
* @param defaultUsername
* the defaultUsername to set
*/
@Value("${EMAIL.DEFAULT.USERNAME}")
public void setDefaultUsername(String defaultUsername) {
EmailUtils.defaultUsername = defaultUsername;
}
/**
* @return the defaultPassword
*/
public static String getDefaultPassword() {
return defaultPassword;
}
/**
* @param defaultPassword
* the defaultPassword to set
*/
@Value("${EMAIL.DEFAULT.PASSWORD}")
public void setDefaultPassword(String defaultPassword) {
EmailUtils.defaultPassword = defaultPassword;
}
/**
* @return the addresseesTO
*/
public static String getAddresseesTO() {
return addresseesTO;
}
/**
* @param addresseesTO
* the addresseesTO to set
*/
@Value("${EMAIL.ADDRESSEESTO}")
public void setAddresseesTO(String addresseesTO) {
EmailUtils.addresseesTO = addresseesTO;
}
//这里使用SpringBoot的@Value注解对配置文件参数进行自动注入,非Spring项目自行设置
}
5.发送测试
@Test
public void fun1() {
EmailUtils.getEmail().
getMail("小猪仔", null, null,
null, "某宝网系统邮件", "<div style='width: 100px;height: 100px;background-color: red;'></div>", TextType.HTML,
Charset.UTF8, null).send();
System.out.println("发送成功");
}
6.常见问题
1、状态码553:
Caused by: com.sun.mail.smtp.SMTPSenderFailedException: 553 Mail from must equal authorized user
原因: 这是由于发件人的邮箱账号和后面连接登陆的账号和密码必须要一致(不要将发件人邮箱填写成收件人邮箱了);
2、状态码554
原因: Ip地址和邮件地址的域名不对应。
3、状态码535
javax.mail.AuthenticationFailedException: 535 Error: authentication failed
原因: 这是由于163的POP3/SMTP/IMAP服务没有开启,需要登陆163邮箱进行操作。