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静态获取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>