JavaMail是SUN提供给广大Java开发人员的一款邮件发送和接受的一款开源类库,支持常用的邮件协议,如:SMTP、POP3、IMAP,开发人员使用JavaMail编写邮件程序时,不再需要考虑底层的通讯细节如:Socket而是关注在逻辑层面。JavaMail可以发送各种复杂MIME格式的邮件内容,注意JavaMail仅支持JDK4及以上版本。虽然JavaMail是JDK的API但它并没有直接加入JDK中,所以我们需要另外添加依赖。
引入依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
属性配置
mail_zh_CN.properties
配置的邮箱需要开通POP3/SMTP服务。
mail.smtp.service=smtp.qq.com
mail.smtp.prot=587
mail.from.address=admin@qq.com
mail.from.smtp.pwd=myihkkyvtxegbahg
mail.from.nickname=admin
数据Model
public class MailEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
// 此处填写SMTP服务器
private String smtpService;
// 设置端口号
private String smtpPort;
// 设置发送邮箱
private String fromMailAddress;
// 设置发送邮箱的STMP口令
private String fromMailStmpPwd;
// 设置邮件标题
private String title;
// 设置邮件内容
private String content;
// 内容格式(默认采用html)
private String contentType;
// 接受邮件地址集合
private List<String> list = new ArrayList<>();
// get set .....
}
public enum MailContentTypeEnum {
HTML("text/html;charset=UTF-8"), //html格式
TEXT("text");
private String value;
MailContentTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
propertiesUtil
public class PropertiesUtil {
private final ResourceBundle resource;
private final String fileName;
/**
* 构造函数实例化部分对象,获取文件资源对象
*
* @param fileName
*/
public PropertiesUtil(String fileName) {
this.fileName = fileName;
Locale locale = new Locale("zh", "CN");
this.resource = ResourceBundle.getBundle(this.fileName, locale);
}
/**
* 根据传入的key获取对象的值
*
* @param key
* properties文件对应的key
* @return String 解析后的对应key的值
*/
public String getValue(String key) {
String message = this.resource.getString(key);
return message;
}
/**
* 获取properties文件内的所有key值<br>
*
* @return
*/
public Enumeration<String> getKeys() {
return resource.getKeys();
}
}
发送邮件
public class MailSender {
// 邮件实体
private static MailEntity mail = new MailEntity();
/**
* 设置邮件标题
*
* @param title
* 标题信息
* @return
*/
public MailSender title(String title) {
mail.setTitle(title);
return this;
}
/**
* 设置邮件内容
*
* @param content
* @return
*/
public MailSender content(String content) {
mail.setContent(content);
return this;
}
/**
* 设置邮件格式
*
* @param typeEnum
* @return
*/
public MailSender contentType(MailContentTypeEnum typeEnum) {
mail.setContentType(typeEnum.getValue());
return this;
}
/**
* 设置请求目标邮件地址
*
* @param targets
* @return
*/
public MailSender targets(List<String> targets) {
mail.setList(targets);
return this;
}
/**
* 执行发送邮件
*
* @throws Exception
* 如果发送失败会抛出异常信息
*/
public void send() throws Exception {
// 默认使用html内容发送
if (mail.getContentType() == null)
mail.setContentType(MailContentTypeEnum.HTML.getValue());
if (mail.getTitle() == null || mail.getTitle().trim().length() == 0) {
throw new Exception("邮件标题没有设置.调用title方法设置");
}
if (mail.getContent() == null || mail.getContent().trim().length() == 0) {
throw new Exception("邮件内容没有设置.调用content方法设置");
}
if (mail.getList().size() == 0) {
throw new Exception("没有接受者邮箱地址.调用targets方法设置");
}
// 读取/resource/mail_zh_CN.properties文件内容
final PropertiesUtil properties = new PropertiesUtil("mail");
// 创建Properties 类用于记录邮箱的一些属性
final Properties props = new Properties();
// 表示SMTP发送邮件,必须进行身份验证
props.put("mail.smtp.auth", "true");
// 此处填写SMTP服务器
props.put("mail.smtp.host", properties.getValue("mail.smtp.service"));
// 设置端口号,QQ邮箱给出了两个端口465/587
props.put("mail.smtp.port", properties.getValue("mail.smtp.prot"));
// 设置发送邮箱
props.put("mail.user", properties.getValue("mail.from.address"));
// 设置发送邮箱的16位STMP口令
props.put("mail.password", properties.getValue("mail.from.smtp.pwd"));
// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用环境属性和授权信息,创建邮件会话
Session mailSession = Session.getInstance(props, authenticator);
// 创建邮件消息
MimeMessage message = new MimeMessage(mailSession);
// 设置发件人
String nickName = MimeUtility.encodeText(properties.getValue("mail.from.nickname"));
InternetAddress form = new InternetAddress(nickName + " <" + props.getProperty("mail.user") + ">");
message.setFrom(form);
// 设置邮件标题
message.setSubject(mail.getTitle());
// html发送邮件
if (mail.getContentType().equals(MailContentTypeEnum.HTML.getValue())) {
// 设置邮件的内容体
message.setContent(mail.getContent(), mail.getContentType());
}
// 文本发送邮件
else if (mail.getContentType().equals(MailContentTypeEnum.TEXT.getValue())) {
message.setText(mail.getContent());
}
// 发送邮箱地址
List<String> targets = mail.getList();
for (int i = 0; i < targets.size(); i++) {
try {
// 设置收件人的邮箱
InternetAddress to = new InternetAddress(targets.get(i));
message.setRecipient(Message.RecipientType.TO, to);
// 最后当然就是发送邮件啦
Transport.send(message);
} catch (Exception e) {
continue;
}
}
}
}
测试
public static void sendMail() throws Exception {
new MailSender().title("测试SpringBoot发送邮件")
.content("简单文本内容发送")
.contentType(MailContentTypeEnum.TEXT)
.targets(new ArrayList<String>() {
{
add("night_ly@126.com");
}
}).send();
}
springboot-email
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
添加配置
spring.mail.host=smtp.qiye.163.com //邮箱服务器地址
spring.mail.username=xxx@oo.com //用户名
spring.mail.password=xxyyooo //密码
spring.mail.default-encoding=UTF-8
mail.fromMail.addr=xxx@oo.com //给谁发邮件
邮件服务
@Component
public class MailServiceImpl implements MailService{
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private JavaMailSender mailSender;
@Value("${mail.fromMail.addr}")
private String from;
@Override
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(content);
try {
mailSender.send(message);
logger.info("简单邮件已经发送。");
} catch (Exception e) {
logger.error("发送简单邮件时发生异常!", e);
}
}
}
other
html格式
MimeMessage message = mailSender.createMimeMessage();
try {
//true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
mailSender.send(message);
logger.info("html邮件发送成功");
} catch (MessagingException e) {
logger.error("发送html邮件时发生异常!", e);
}
附件格式
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
helper.addAttachment(fileName, file);
mailSender.send(message);
logger.info("带附件的邮件已经发送。");
} catch (MessagingException e) {
logger.error("发送带附件的邮件时发生异常!", e);
}
静态资源
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);
mailSender.send(message);
logger.info("嵌入静态资源的邮件已经发送。");
} catch (MessagingException e) {
logger.error("发送嵌入静态资源的邮件时发生异常!", e);
}
邮件模板
1.添加thymeleaf包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.添加模板emailTemplate.html
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
您好,这是验证邮件,请点击下面的链接完成验证,<br/>
<a href="#" th:href="@{ http://www.ityouknow.com/neo/{id}(id=${id}) }">激活账号</a>
</body>
</html>
3.使用模板发送邮件
//创建邮件正文
Context context = new Context();
context.setVariable("id", "006");
String emailContent = templateEngine.process("emailTemplate", context);
mailService.sendHtmlMail("ityouknow@126.com","主题:这是模板邮件",emailContent);
发送失败
因为各种原因,总会有邮件发送失败的情况,比如:邮件发送过于频繁、网络异常等。在出现这种情况的时候,我们一般会考虑重新重试发送邮件,会分为以下几个步骤来实现:
1、接收到发送邮件请求,首先记录请求并且入库。
2、调用邮件发送接口发送邮件,并且将发送结果记录入库。
3、启动定时系统扫描时间段内,未发送成功并且重试次数小于3次的邮件,进行再次发送