中心思想:
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中,这里不做详细解释。
设计表的定义大致如下↓
id | subject | email_body | sned_flg | creat_user | creat_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("[email protected]");//邮箱地址(QQ邮箱为例)
sender.setUsername("username");//对应邮箱的用户名
sender.setPassword("password");//密码
sender.setDefaultEncoding(StandardCharsets.UTF_8.toString());//邮件编码方式
Properties p = new Properties();
p.put("mail.smtp.host", "[email protected]");
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的时间片
文章评论