设计一套发信功能(SpringBoot+freemarker)

中心思想:
1将送信内容放到Map里
2将Map里的数据铺到templates
3将templates的内容放到数据库做持久化
4读数据库的邮件内容进行发送

引入模板引擎依赖

        <!-- 模板-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

设计发信模板
将模板放入
resource/templates文件夹下

<html>
<head>
<style>
    table.recall { border: 1px solid #808080; border-collapse:collapse;} 
    table.recall td { border: 1px solid #808080; border-collapse:collapse; padding:3px} 
    table.recall th { border: 1px solid #808080; border-collapse:collapse; padding:3px} 
</style>
</head>
<body>
     <div>${textHeader}</div>
        <table class="recall">
          <thead bgcolor="#99ff33">
            <tr>
            <th>name</th>
            <th>school</th>
            <th>rule</th>
            <th>address</th>
            <th>code</th>
            <th>age</th>
            </tr>
          </thead>
          <tbody>
            <#list text as deal>
               <tr>
                  <td >
                    ${deal.name}
                  </td>
                  <td>
                    ${deal.school}
                  </td>
                  <td>
                    ${deal.rule}
                  </td>
                  <td>
                    ${deal.address}
                  </td>
                  <td> 
                    ${deal.code}
                  </td>
                  <td> 
                    ${deal.age}
                  </td>
                </tr>
             </#list>
            </tbody>
        </table>
        <br>
        <nobr>${textFooter}</nobr><br>
</body>
</html>

 写共通方法(将发信内容铺在模板里面)
 

package com.syan.cloudbiz2.util;


import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import freemarker.template.Configuration;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.util.Map;

@Component
public class MailUtils {
    @Autowired
    private Configuration freemarkerConfig;

 public String getHtmlBody(Map<String,Object> map)throws Exception{
     //将/templates文件夹下模板加载进去
     freemarkerConfig.setClassForTemplateLoading(this.getClass(),"/templates");
     //得到想要的模板
     Template t =freemarkerConfig.getTemplate("email.ftl");
     //将数据铺进去,并返回字符串
     String html=FreeMarkerTemplateUtils.processTemplateIntoString(t,map);
     return html;
 }

}

测试一下:
 

    public String checkUp( UserEntity userEntity)throws Exception {
        Map<String,Object> result = new HashMap<>();
        List<SendEmailModel> list =new ArrayList<>();
        SendEmailModel dd =new SendEmailModel();
        dd.setAddress("com.dd");
        dd.setCode("11");
        dd.setName("meili");
        dd.setRule("teacher");
        dd.setSchool("gaoxinyizhong");
        dd.setAge("27");
        Map<String,Object> map = new HashMap<>();
        map.put("text",list);
        map.put("textHeader","head");
        map.put("textFooter","foot");
        String html =mail.getHtmlBody(map);
     return html;
    }

结果:

将结果放在html上

 然后再将html内容放在mysql中,这里不做详细解释。
设计表的定义大致如下↓

idsubjectemail_bodysned_flgcreat_usercreat_dt

最后一步:发信(也是最重要的一步)
因为这块可能回循环送信
 

package com.syan.cloudbiz2.service;

import com.syan.cloudbiz2.dto.SendEmailModel;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class SendEmailService {

    @Autowired
    private SendEmService sendEmService;

  public void mailSend(List<SendEmailModel> mailList){
      mailList.forEach(k->{
                  try {
                      sendEmService.sendmil();
                  } catch (Exception e) {
                      e.printStackTrace();
                  }

              }
      );
  }
}

送信机能
这块用到了一个知识点
 @Transactional(propagation= Propagation.REQUIRES_NEW)事务的传播机制
如果一下发一万封 不能有一条出错就全部回滚了。

package com.syan.cloudbiz2.service;

import com.syan.cloudbiz2.dto.SendMessageDto;
import com.syan.cloudbiz2.util.MailUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SendEmService {
@Autowired
private MailUtils mailUtils;
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public boolean sendmil() throws Exception {
        SendMessageDto ss =new SendMessageDto();
        ss.setFrom("qq.com");
        ss.setCc("qq.com");
        ss.setBcc("qq.com");
        ss.setSubject("haha");
        ss.setText("html");
        mailUtils.sendmailstart(ss);
        return false;
    }
}

MailUtil.java
 

    public synchronized boolean sendmailstart(SendMessageDto sendMessageDto) throws Exception {
        try {
            JavaMailSenderImpl sender=new JavaMailSenderImpl();
            sender.setHost("wenwenyu@qq.com");//邮箱地址(QQ邮箱为例)
            sender.setUsername("username");//对应邮箱的用户名
            sender.setPassword("password");//密码
            sender.setDefaultEncoding(StandardCharsets.UTF_8.toString());//邮件编码方式
            Properties p = new Properties();
            p.put("mail.smtp.host", "wenwenyu@qq.com");
            p.put("mail.smtp.port", "465");
            p.put("mail.smtp.auth", "false");//是否需要开启邮箱验证
            p.put("mail.smtp.timeout",10000);//时间延迟
            p.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");//设置为SSL协议
            sender.setJavaMailProperties(p);
            MimeMessage message = sender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(sendMessageDto.getFrom());
            helper.setTo(sendMessageDto.getTo());
            helper.setCc(sendMessageDto.getCc());
            helper.setBcc(sendMessageDto.getBcc());
            helper.setSubject(sendMessageDto.getSubject());
            helper.setText(sendMessageDto.getText());

            try{
                sender.send(message);
            }catch(MailException e){
                sender.send(message);
            }
            Thread.sleep(100);
            return true;
        }catch (Exception e){
           throw new Exception("ddd");
        }
    }

 这部分用到一个Thread.sleep(100);
线程睡眠0.1秒的作用是让系统重新计算线程的优先级,因为window系统是线程抢占cpu的时间片,如果此时发送失败继续发送,有可能发生死锁,这个线程可能一直会抢占cpu的时间片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值