1. 加入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2. 增加yml配置
JavaMailSender配置
#邮箱配置
spring:
mail:
host: "smtp.163.com"
username: "XXXX_job@163.com"
#非邮箱登陆秘密;而是成功开启IMAP/SMTP服务,第三方客户端登录时的授权密码
password: "XXXXXXXXXXXX"
default-encoding: UTF-8
# 收件人 可以多个配置用";"隔开
toMailAddr: XXXX@qq.com;XXXX@163.com
# 抄送人 可以多个配置用";"隔开
cc: XXXX@qq.com;XXXX@163.com
模板引擎配置
spring
freemarker:
allow-request-override: false
check-template-location: true
charset: utf-8
content-type: text/html
expose-request-attributes: false
expose-session-attributes: false
expose-spring-macro-helpers: false
cache: true
3.编写Java代码
工具类
静态获取ioc中注入类,方便工具类获取
@Component
public class BeanUtil implements ApplicationContextAware {
private static Logger log = LoggerFactory.getLogger(BeanUtil.class);
private static ConfigurableApplicationContext applicationContext;
public static void createBean(Object o) {
String beanName = o.getClass().getName();
// 获取bean工厂并转换为DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext
.getBeanFactory();
// 注册bean
defaultListableBeanFactory.registerSingleton(beanName, o);
log.info("register bean " + applicationContext.getBean(o.getClass()));
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static Object getBeanWithEx(String name) {
Object obj = getBean(name);
if (obj == null) {
throw new RuntimeException("no bean name " + name + " found");
}
return obj;
}
public static <T> T getBeanWithEx(Class<T> clazz) {
T obj = getBean(clazz);
if (obj == null) {
throw new RuntimeException("no " + clazz.getName() + " bean found");
}
return obj;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanUtil.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
public static void triggerEvent(ApplicationEvent event) {
if (applicationContext != null) {
applicationContext.publishEvent(event);
}
}
}
配置类
使用配置类方便插拔,即配即用,解耦合
package XXXXXX.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties("spring.mail")
public class MailConfig {
/**
* 服务器地址
*/
private String host;
/**
* 发信箱邮箱账号
*/
private String username;
/**
* 抄送邮箱账号 可以多个配置用";"隔开
*/
private String cc;
/**
* 收信箱邮箱账号 可以多个配置用";"隔开
*/
private String toMailAddr;
}
邮件发送工具类
有简单邮件发送和模板邮件发送
import XXXX.MailConfig;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class MailUtil {
private static final String MAIL_SPLIT = ";";
private static JavaMailSender mailSender = BeanUtil.getBean(JavaMailSender.class);
private static MailConfig mailConfig = BeanUtil.getBean(MailConfig.class);
private static FreeMarkerConfig freeMarkerConfig = BeanUtil.getBean(FreeMarkerConfig.class);
/**
* 发送简单邮件信息
* 使用请配置邮箱信息 参考
* mail:
* host: "smtp.163.com"
* username: "XXXXXX@163.com"
* password: "XXXXXX" 非邮箱登陆秘密;而是成功开启IMAP/SMTP服务,第三方客户端登录时的授权密码
* default-encoding: UTF-8
*
* @param content 邮件内容
* @param subject 邮件标题
* @return boolean 发送是否成功
*/
public static boolean sendSimpleMail(String content, String subject) {
//邮件信息封装
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(mailConfig.getUsername());
message.setTo(mailConfig.getToMailAddr().split(MAIL_SPLIT));
if (StringUtils.isNotBlank(mailConfig.getCc())) {
message.setCc(mailConfig.getCc().split(MAIL_SPLIT));
}
message.setSubject(subject);
message.setText(content);
try {
mailSender.send(message);
} catch (Exception e) {
log.error(String.format("邮件发送失败;【mailAddr:%s, cc:%s, subject:%s, content:%s 】", mailConfig.getToMailAddr(), mailConfig.getCc(), subject, content), e);
return false;
}
return true;
}
/**
* 模板邮件发送
*
* @param params 发送邮件的主题对象 <desc>封装数据类,字段参看email模板</desc>
* @param title 邮件标题
* @param templateName 模板名称
*/
public static void sendMessageMail(Object params, String title, String templateName) {
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(mailConfig.getUsername());
helper.setTo(mailConfig.getToMailAddr().split(MAIL_SPLIT));
if (StringUtils.isNotBlank(mailConfig.getCc())) {
helper.setCc(mailConfig.getCc().split(MAIL_SPLIT));
}
//邮件标题
helper.setSubject(String.format("【%s-%s %s】", title, LocalDate.now(), LocalTime.now().withNano(0)));
Map<String, Object> model = new HashMap<>();
model.put("params", params);
try {
Template template = freeMarkerConfig.getConfiguration().getTemplate(templateName);
try {
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
helper.setText(text, true);
mailSender.send(mimeMessage);
} catch (TemplateException e) {
log.error(String.format("邮件发送失败;【params:%s, title:%s, templateName:%s 】", params, title, templateName), e);
e.printStackTrace();
}
} catch (IOException e) {
log.error(String.format("邮件发送失败;【params:%s, title:%s, templateName:%s 】", params, title, templateName), e);
e.printStackTrace();
}
} catch (MessagingException e) {
log.error(String.format("邮件发送失败;【params:%s, title:%s, templateName:%s 】", params, title, templateName), e);
e.printStackTrace();
}
}
}
模板邮件文件
在resources文件下创建templates文件夹,加入文件emailTest.ft
<meta charset="UTF-8"> <title>消息通知</title> </head> <style type="text/css"> table { font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; width: 100%; border-collapse: collapse; } td, th { font-size: 1em; border: 1px solid #5B4A42; padding: 3px 7px 2px 7px; } th { font-size: 1.1em; text-align: center; padding-top: 5px; padding-bottom: 4px; background-color: #24A9E1; color: #ffffff; } </style> <body> <div> <h2>邮件消息通知</h2> <table id="customers"> <tr> <th>主题</th> <th>介绍</th> <th>内容</th> </tr> <tr> <td>${(params.messageCode)!""}</td> <td>${(params.messageStatus)!""}</td> <td>${(params.cause)!""}</td> </tr> </table> </div> </body> </html>
模板邮件数据模型类
@Data
public class TestMailMessage implements Serializable {
private String messageCode;
private String messageStatus;
private String cause;
}
测试类
@RestController
@RequestMapping("mail")
public class MailTestController {
@RequestMapping("testSendMail")
public ResultBean testSendMail(String to, String cc) {
boolean test_simple_mail = MailUtil.sendSimpleMail( " hello text simple mail", "test simple mail");
return ResultBean.ok(test_simple_mail);
}
@GetMapping("/send")
public String send(String test){
TestMailMessage message = new TestMailMessage();
message.setMessageCode("XXXXXXX");
message.setMessageStatus("服务对数据库读写压力大");
message.setCause(test);
MailUtil.sendMessageMail(message, "测试消息通知", "emailTest.ft");
return "1";
}
}