SpringBoot+Freemarker+Quartz 實現定時郵件推送

近期項目中有定時郵件推送的需求,經過一番實踐,最終實現,因此將開發步驟記錄下來:

涉及的技術:

SpringBoot:v1.5.13.RELEASE

Freemarker:2.0

Springcloud:Dalston.SR3

Quartz 

1.引入依賴,分別爲SpringBoot對mail和freemarker模板的集成

<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.配置發送郵箱,bootstrap.yml中配置如下

# 發送郵件配置
  freemarker:
    f
  mail:
    host: 127.0.0.0
    port: xxx
    username: xxx
    password: xxx
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          ssl:
            checkserveridentity: false
            trust: 127.0.0.0

3.新建定時任務類JobBusiness ,實現BusinessAgent 

public class JobBusiness implements BusinessAgent {
	
	@Override
	public void execute(String configId, Map jobMap, List jobList) {
	  JobService jobService = ApplicationObjectUtils.getBean(JobService.class);
	  jobService .sendMail();
	}
}

4.新建發送郵件接口JobService

public interface JobService {

    void sendMail();
}

5.新建發送郵件JobServiceImpl

@Service
public class JobServiceImpl extends MybatisManagerImpl implements JobService{

    private static final Logger logger = LoggerFactory.getLogger(JobService.class);

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Autowired
    private JavaMailSender javaMailSender;

    private static final String FROM = "[email protected]";
    private String toarray [] = {"[email protected]"};
    private String bcc [] = {"[email protected]"};

    @Override
    public void sendMail() {
        List<Map> list = this.myBatisDao.getSqlSession().selectList("geiMailQuery");
        if(list.size() == 0){
            log.info(""+getToday()+",沒有待推送的郵件,本次任務結束!");
            return;
        }
        String title = "訂閱:xxx("+getToday()+")";
        //initConfig();//獲取redis的收件人、抄送人郵箱
        sendEmail(list,title,toarray, bcc, "Mail.ftl");
    }


    public R sendEmail(List<Map> list, String subject, String[] to, String[] cc, String templateName){
        Long startTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("list", list);
        try {
            if (StringUtils.isEmpty(subject)) {
                log.error("發送郵件失敗,主題不能爲空!");
                return R.success("發送郵件失敗,主題不能爲空!");
            }
            if (to.length == 0) {
                log.error("發送郵件失敗,收件人不能爲空!");
                return R.success("發送郵件失敗,收件人不能爲空!");
            }
            //調用發送模塊
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            //設置發件信息人
            helper.setFrom(FROM);
            //設置標題
            helper.setSubject(subject);
            helper.setTo(to);
            //抄送
            if (cc.length > 0) {
                helper.setCc(cc);
            }
            //密送
            //helper.setBcc(bccList);
            //獲取模板
            Configuration configuration = freeMarkerConfigurer.getConfiguration();
            Template template = configuration.getTemplate(templateName, "UTF-8");
            String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
            helper.setText(text, true);
            //發送
            javaMailSender.send(mimeMessage);
            //附件,後續支持
            //Resource resource = new ClassPathResource("xxx.jpg");
            //helper.addInline("contentId", resource);
            Long endTime = System.currentTimeMillis();
            log.info("郵件發送成功 耗時:" + (endTime - startTime) / 1000 + "s");
            return R.success("郵件發送成功");
        } catch (Exception e) {
            log.error("發送郵件失敗:" + e.getMessage());
            return R.success("郵件發送成功");
        }
    }


    private String getToday(){
        Date date = new Date();
        return new SimpleDateFormat("yyyy-MM-dd").format(date);
    }

注:R爲封裝的一個返回類,具體的返回類型可以自己定義 

6.以163郵箱爲發送服務器(測試能發)

public R send163Email(List<Map> list, String subject, String[] to, String[] cc, String templateName){
        Long startTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("list", list);
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.163.com");
        props.put("mail.smtp.auth", "true");
        props.put("username", "xxx");
        props.put("password", "xxx");//此處爲smtp的密碼,非郵箱密碼
        MimeMessage mimeMessage = null;
        try {
            if (StringUtils.isEmpty(subject)) {
                log.error("發送郵件失敗,主題不能爲空!");
                return R.success("發送郵件失敗,主題不能爲空!");
            }
            if (to.length == 0) {
                log.error("發送郵件失敗,收件人不能爲空!");
                return R.success("發送郵件失敗,收件人不能爲空!");
            }
            InternetAddress fromAddress = new InternetAddress("[email protected]");
            // toemails(字符串,多個收件人用,隔開)
            Session mailSession = Session.getDefaultInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("[email protected]", "xxx");//此處爲smtp的密碼,非郵箱密碼
                }
            });
            mimeMessage = new MimeMessage(mailSession);
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            //設置發件信息人
            helper.setFrom(FROM);
            //設置標題
            helper.setSubject(subject);
            helper.setTo(to);
            //抄送
            if (cc.length > 0) {
                helper.setCc(cc);
            }
            //密送
            //helper.setBcc(bccList);
            //獲取模板
            Configuration configuration = freeMarkerConfigurer.getConfiguration();
            Template template = configuration.getTemplate(templateName, "UTF-8");
            String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
            helper.setText(text, true);
            mimeMessage.saveChanges();
            Transport.send(mimeMessage);
            Long endTime = System.currentTimeMillis();
            log.info("郵件發送成功 耗時:" + (endTime - startTime) / 1000 + "s");
        } catch (Exception e) {
            log.error("Error while sending mail." + e.getMessage(), e);
        }

7.新建Mail.ftl郵件模板,位置:resources/templates

<!DOCTYPE html>
<html lang="zh">
<head>
    <META http-equiv=Content-Type content='text/html; charset=UTF-8'>
    <title>Title</title>
    <style type="text/css">

        table.gridtable {
            font-family: verdana,arial,sans-serif;
            text-align:center;
            font-size:11px;
            color:#333333;
            border-width: 1px;
            border-color: #666666;
            border-collapse: collapse;
            word-break: keep-all;
        }
        table.gridtable th {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #666666;
            background-color: #B7DEE8;
        }
        table.gridtable td {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #666666;
            background-color: #ffffff;
        }


        h3 {
            font-size: 1.8em;
            margin: 2px 0;
            line-height: 1.8em;
        }
    </style>
</head>
<body>
<p style="font-family:&quot;font-size:13px;background-color:#FFFFFF;">
    各位同事大家好!
<div>
    系統內以下數據異常,請覈實處理!
</div>
</p>
<table class="gridtable">
    <tr>
        <th>序號</th>
        <th>xx</th>
        <th>xx</th>
        <th>xx</th>
        <th>xx</th>
        <th>xx</th>
        <th>xx</th>
    </tr>
    <#list list as data>
        <tr>
            <th>
                ${data.xx}
            </th>
            <td>
                ${data.xx}
            </td>
            <td>
                ${data.xx}
            </td>
            <td>
                <strong style="color:red">${data.xx}</strong>
            </td>
            <td>
                <strong style="color:red">${data.xx?if_exists}</strong>
            </td>
            <td>
                ${data.xx?if_exists}
            </td>
            <td>
                ${data.xx?if_exists}
            </td>
        </tr>
    </#list>
</table>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<span style="font-family:&quot;font-size:13px;background-color:#FFFFFF;">xxx有限公司</span><br />
<span style="font-family:&quot;font-size:13px;background-color:#FFFFFF;">xxx</span><br />
<p>
    <span style="font-family:&quot;font-size:13px;background-color:#FFFFFF;">郵箱:[email protected]&nbsp;</span>
</p>
<p>
    <span style="font-family:&quot;font-size:13px;background-color:#FFFFFF;">地址:xxx</span>
</p>
<hr color="red" size="“5”" style="font-size: 14px; line-height: 21px; font-family: Verdana;" />
<p style="margin: 0px 0cm; widows: 1; line-height: 15.75pt; font-size: 12pt; font-family: 宋體; background-color: rgb(255, 255, 255);"><span lang="EN-US" style="font-size: 10.5pt; font-family: Calibri, sans-serif; color: rgb(31, 73, 125);"><font size="1" style="color: rgb(0, 0, 0); widows: 2; font-family: Verdana;">系統定時發送,如果收件有誤,請將此郵件刪除,謝謝</font></span></p>
<br/>
<br/>
</body>
</html>

注意: 如果data.xxx可能爲null,則後面加:?if_exists,否則ftl頁面將報錯

8.收到的郵件如下圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章