JAVA && Spring && SpringBoot2.x — 学习目录
SpringBoot中使用Freemarker构建邮箱模板
SpringBoot2.x整合SMTP邮件服务(配置篇)
当邮件内容比较简单的时候,我们可能一行字符串就能表达出意思,但是绝大多数情况下,我们的邮件内容都比较复杂需要使用HTML来组织邮件内容。并且HTML中的数据还要动态修改,这时,最好的解决方案莫过于Freemarker。
Freemarker不仅可以做HTML模板(大多数情况下它都扮演了这个角色)。还可以XML、邮件等的模板。那么我们便看一下Freemarker要怎么使用。
1. 引入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
2. 创建邮件地址
需要根据我们想要的HTML样式,常见一个邮件模板,这个模板是ftl文件。
<p>你好,${name}童鞋,欢迎加入XXX大家庭!您的入职信息如下:</p>
<table border="1" cellspacing="0">
<tr><td><strong style="color: #F00">工号</strong></td><td>${workID}</td></tr>
<tr><td><strong style="color: #F00">合同期限</strong></td><td>${contractTerm}年</td></tr>
<tr><td><strong style="color: #F00">合同起始日期</strong></td><td>${beginContract?string("yyyy-MM-dd")}</td></tr>
<tr><td><strong style="color: #F00">合同截至日期</strong></td><td>${endContract?string("yyyy-MM-dd")}</td></tr>
<tr><td><strong style="color: #F00">所属部门</strong></td><td>${departmentName}</td></tr>
<tr><td><strong style="color: #F00">职位</strong></td><td>${posName}</td></tr>
</table>
<p><strong style="color: #F00; font-size: 24px;">希望在未来的日子里,携手共进!</strong></p>
3. 显示效果
样式可以根据自己的需求进行灵活调整,但是需要注意的是:一般在前后端分离中,不需要webapp目录,模板一般放在resources目录下的ftl目录。
4. 模板解析
Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
cfg.setClassLoaderForTemplateLoading(ClassLoader.getSystemClassLoader(),"ftl");
Template emailTemplate = cfg.getTemplate("email.ftl");
StringWriter out = new StringWriter();
emailTemplate.process(employee,out);
- 根据所使用的freemarker版本号创建一个Configuration对象 。
- 设置模板路径,模板路径的设置方法有好几个,我这里因为放在了resources目录下,因此使用了setClassLoaderForTemplateLoading方法
- 创建模板,通过process方法进行渲染,渲染后的html将放到out这个变量中,然后我们在邮件中直接将之发送出去即可。
2. SpringBoot整合email
Spring中文文档—使用MimeMessageHelper发送邮件
SpringEmail抽象的核心是MailSender接口,MailSender的实现能够把Email发送给邮件服务器,由邮件服务器实现邮件发送的功能。
Spring自带一个MailSender的实现JavaMailSenderImpl,他会使用JavaMail API来发送Email。Spring或SpringBoot在发送Email之前。我们必须要JavaMailSenderImpl装配为Spring应用上下文的一个Bean。
2.1 引入Maven文件
<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.2 配置application.yml
server:
port: 8080
spring:
mail:
host: smtp.qq.com
username: #发送方邮箱账号
password: #授权码,并非登录密码
default-encoding: utf-8
protocol: smtp
properties:
mail:
smtp:
ssl.trust: smtp.qq.com
socketFactory:
class: javax.net.ssl.SSLSocketFactory #SSL证书Socket工厂
port: 465 #使用SMTPS协议465端口
auth: true
starttls:
enable: true
required: true
thymeleaf:
prefix: classpath:/templates/
在此处需要说明一下:邮件发送端口默认为smtp协议的25端口,但是项目需要部署到阿里云,因为阿里云默认屏蔽掉了25端口,所以此处需要更换smtps协议465端口。
2.3 配置javabBean模板
public class MailVerifyCode {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
2.4 配置邮件发送的ftl模板
需要注意的是:要存放在resource目录下的templates文件夹下。当中的${params.username}是EL表达式,需要代码中进行配置。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>修改密码</title></head>
<body>
<table cellspacing="0" cellpadding="0" width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;">
<tbody>
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"> </td>
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;">
<table cellspacing="0" cellpadding="0" width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<tbody>
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; text-align: center; margin: 0; padding: 20px;">
<table cellspacing="0" cellpadding="0" width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;background-color: #fff">
<tbody>
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;"> <h1 style="font-family: 'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif; box-sizing: border-box; font-size: 32px; color: #000; line-height: 1.2em; font-weight: 500; text-align: center; margin: 40px 0 0;">
<img style="height:32px;" alt="" /></h1> </td>
</tr>
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;"> <h1 style="font-family: 'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif; box-sizing: border-box; font-size: 24px; color: #000; line-height: 1.2em; font-weight: 500; text-align: center; margin: 40px 0 0;"> 需要您的注意</h1> </td>
</tr>
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;">
<h1 style="padding-bottom:60px;font-family: 'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif; box-sizing: border-box; font-size: 20px; color: #000; line-height: 1.2em; font-weight: 500; text-align: center; margin: 40px 0 0;">
<p>${(params.username)!""}</p>
<p>您现在正在做修改密码操作,</p>
<p>验证码为 <span style="color:#3dabff;font-weight: bolder;">${(params.code)!""}</span>,
</p> <p>请不要把验证码告诉别人哦!</p>
</h1></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"> </td>
</tr>
</tbody>
</table>
</body>
</html>
2.5 配置最大超时时间的邮件发送
@Component
public class FreeMarker {
@Value("${spring.mail.username}")
private String sender;
@Resource
private JavaMailSender javaMailSender;
@Resource
private FreeMarkerConfigurer configurer;
public String sendMailCode(String toMail) throws Exception{
final String title = "标题";
final ExecutorService exec = Executors.newSingleThreadExecutor();
Callable<String> call = () -> {
try {
String code = getMailCode();
MailVerifyCode verifyCode = new MailVerifyCode();
verifyCode.setCode(code);
sendMail(verifyCode,title,"updatePsw.ftl",toMail);
return code;
}catch (Exception e){
throw new Exception("发送失败",e);
}
};
try {
Future<String> future = exec.submit(call);
String code = future.get(1000*10*1000, TimeUnit.MILLISECONDS);//设置超时响应时间为10s
return code;
}catch (Exception e){
throw new Exception("发送失败",e);
}finally {
exec.shutdown();
}
}
public String getMailCode(){
String code = String.valueOf((int)((Math.random()*9 +1)*100000));
return code;
}
/**
*
* @param params 模板参数
* @param title 标题
* @param templateName 模板名称
* @param to 收件方
* @throws Exception
*/
public void sendMail(Object params,String title,String templateName,String to) throws Exception{
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//防止成为垃圾邮件,披上outlook的马甲
mimeMessage.addHeader("X-Mailer","Microsoft Outlook Express 6.00.2900.2869");
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
//设置发送方
helper.setFrom(sender);
//设置收件方
helper.setTo(InternetAddress.parse(to));
//设置发送邮件数据,填入到模板中
Map<String,Object> model = new HashMap<>();
model.put("params",params);
//读取邮件模板
Template template = configurer.getConfiguration().getTemplate(templateName);
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template,model);
helper.setText(text,true);
//设置标题
helper.setSubject(title);
//发送邮件
javaMailSender.send(mimeMessage);
}
}
2.6 单元测试
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class TestEmail {
@Autowired
private FreeMarker freeMarker;
@Test
public void emailTest(){
try {
freeMarker.sendMailCode("接受方的邮件地址");
} catch (Exception e) {
e.printStackTrace();
}
}
}