前几天由于业务需要 实现注册.投保.出单.等过程都需要发送邮件 ,由于邮件太多我想到了个模板化操作,使用了比较熟悉的freemaker 轻松解决了20+种邮件的发送。
freemaker入门教程传送门:https://blog.csdn.net/xxk666/article/details/85323044
接下里废话不多说 咱们一步一步来看看怎么实现的 ,我会发3【普通邮件,html格式邮件,附件类邮件】种类型进行开发
javax.mail
mail
1.4.5
org.springframework.boot
spring-boot-starter-mail
org.springframework.boot
spring-boot-starter-thymeleaf
## 发送邮件服务
mail:
host: //host地址(可以在你的邮箱设置里找到)
port: 465 //端口号
username: //发送邮件邮箱
password: //开启POP3/SMTP服务时生成的链接字符
protocol: smtp //类型(默认smtp)
properties:
mail:
smtp:
auth: true //必须开启
default-encoding: UTF-8
邮件内容bean:
@Data
public class MailBean {
/**
* 收件人邮箱
*/
private String email;
/**
* 邮件主题
*/
private String subject;
/**
* 邮件内容
*/
private String text;
/**
* 附件
*/
private InputStreamSource file; //资源服务器下载
private FileSystemResource file2; //freemaker生成在本地的临时文件
/**
* 附件名称
*/
private String attachmentFilename;
private String attachmentFilename2;
/**
* 内容ID,用于发送静态资源邮件时使用
*/
private String contentId;
public static MailBean getMailBean() {
return new MailBean();
}
HTML参数bean(DTO)
package com.jt.www.model.mail.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @Description: 接收前端发送的参数
* @author: xuxinku
* @Date: 2019/6/16 14:13
* @ModifiedDate:
* @Copyright:江泰保险股份有限公司
*/
@Getter
@Setter
public class MailDTO {
// usercode 投保人code
@ApiModelProperty(value = "投保人code")
private String userCode;
// userName 投保人名称
@ApiModelProperty(value = "投保人名称")
private String userName;
//原因 reason
@ApiModelProperty(value = "原因")
private String reason;
@ApiModelProperty(value = "保险类型 全国职业院校学生实习责任保险项目01 /学生安全责任保险 02 ")
private String insuranceType;
//订单号 orderNo
@ApiModelProperty(value = "订单号")
private String orderNo;
// 保单号
@ApiModelProperty(value = "保单号")
private String proposalNo;
// 投保单号
@ApiModelProperty(value = "投保单号")
private List policyNo;
// 综合投保单
@ApiModelProperty(value = "综合投保单")
private String zhPolicyNo;
// 保险起期
@ApiModelProperty(value = "保险/批单起期")
private String startDate;
// 保险止期
@ApiModelProperty(value = "保险止期")
private String endDate;
// 投保单id
@ApiModelProperty(value = "投保单id")
private String policyId;
// 投保清单id
@ApiModelProperty(value = "投保清单id")
private String policyExcelId;
// 保费
@ApiModelProperty(value = "保费")
private String premium;
// 户名
@ApiModelProperty(value = "户名")
private String account;
// 开户行
@ApiModelProperty(value = "开户行")
private String bank;
// 账号
@ApiModelProperty(value = "银行账号")
private String number;
// 批改申请号
@ApiModelProperty(value = "批改申请号")
private String correctNo;
// 批改保险起期
@ApiModelProperty(value = "批改保险起期")
private String pdStartDate;
// 收件单位
@ApiModelProperty(value = "收件单位")
private String receiveOrg;
// 收件人email
@ApiModelProperty(value = "收件人email")
private String email;
// 出单邮件中收件人email
@ApiModelProperty(value = "出单邮件中收件人email")
private String cdEmail;
// 山东地区
@ApiModelProperty(value = "山东地区行政区划编码")
private String regionCode;
// 山东地区
@ApiModelProperty(value = "山东地区")
private String region;
// 山东地区
@ApiModelProperty(value = "山东地区专用邮箱")
private String sdRegionEmail;
//地区编码
@ApiModelProperty(value = "地区编码")
private String areaCode;
//产品编码
@ApiModelProperty(value = "产品编码")
private String productCode;
//产品名称
@ApiModelProperty(value = "产品名称")
private String productName;
}
/**
* 发送邮件测试方法
*/
public void sendMail() {
SimpleMailMessage mimeMessage = new SimpleMailMessage();
mimeMessage.setFrom(“[email protected]"); //发件人邮箱
mimeMessage.setTo("[email protected]");//发件人邮箱
mimeMessage.setSubject("SpringBoot集成JavaMail实现邮件发送");
mimeMessage.setText("SpringBoot集成JavaMail实现邮件发送正文");
mailSender.send(mimeMessage);
}
/**
* 发送简易邮件
* @param mailBean
*/
public void sendMail(MailBean mailBean) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
try {
helper.setFrom(“[email protected]");
helper.setTo(“[email protected]");
helper.setSubject("SpringBoot集成JavaMail实现邮件发送");
helper.setText("SpringBoot集成JavaMail实现邮件发送正文");
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
public void sendMailHtml(MailBean mailBean) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
try {
helper.setFrom(“[email protected]");
helper.setTo(“[email protected]");
helper.setSubject("SpringBoot集成JavaMail实现邮件发送");
helper.setText("SpringBoot集成JavaMail实现邮件发送内容", true); //true 代表发送HTML
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
调用发送HTML邮件
/**
* 注册信息提交通知【1】
* @param mailDTO 前端参数信息
*/
public void ZCXXTJ(MailDTO mailDTO){
MailBean mailBean = new MailBean();
Context context = new Context();
context.setVariable("userdate", DateUtils.getCurrentTime()); //获取当前时间
String content = templateEngine.process("01emailTemplate", context); // 模板: 参数
mailBean.setSubject("注册信息提交通知");
mailBean.setText(content);
mailBean.setEmail(mailDTO.getEmail());
mailUtil.sendMailHtml(mailBean); //调用接口
}
HTML模板
Insert title here
尊敬的用户:
您好!您在xx网填写的认证信息已提交成功,请等待客户经理审核。
注册认证信息审核通过后,您可登录教保网操作线上投保。
xx保险经纪股份有限公司
util:
/**
* 发送邮件-附件邮件
* @param mailBean
*/
public void sendMailAttachment(MailBean mailBean) {
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(“[email protected]");
helper.setTo(“[email protected]");
helper.setSubject(“邮件名称”);
helper.setText(“邮件内容”, true);
// 增加附件名称和附件
if(null!=mailBean.getFile()){
helper.addAttachment(mailBean.getAttachmentFilename(), mailBean.getFile());
}
if(null!=mailBean.getFile2()){
helper.addAttachment(mailBean.getAttachmentFilename2(), mailBean.getFile2());
}
mailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
调用方法【1.资源服务器下载】:
/**
* 出单成功通知邮件-----云南【021】
*
* 云南
*
* @param mailDTO
*/
public void CDCG2(MailDTO mailDTO){
MailBean mailBean = new MailBean();
Context context = new Context();
context.setVariable("user", mailDTO.getUserName());
context.setVariable("productName", mailDTO.getProductName());
context.setVariable("orderNo", mailDTO.getOrderNo());
List policyNo = mailDTO.getPolicyNo();
StringBuilder policyNos = new StringBuilder();
for (String pol:policyNo) {
policyNos.append(pol+". ");
}
context.setVariable("policyNo", policyNos);
context.setVariable("proposalNo", mailDTO.getProposalNo());
context.setVariable("userdate", DateUtils.getCurrentTime());
String content = templateEngine.process("21emailTemplate", context);
mailBean.setSubject("出单成功通知邮件");
mailBean.setText(content);
//附件2 资源下载
Response downloadFile = filesClient.downloadFile(Long.parseLong(mailDTO.getPolicyId()));
Response.Body body = downloadFile.body();
InputStream inputStream =null;
InputStreamSource iss =null;
try {
inputStream = body.asInputStream();
byte[] bytes = readInputStream(inputStream);
iss = new ByteArrayResource(bytes);
} catch (IOException e) {
e.printStackTrace();
}
mailBean.setFile(iss);
mailBean.setAttachmentFilename("电子保单.pdf");
mailBean.setEmail(mailDTO.getEmail());
mailUtil.sendMailAttachment(mailBean);
}
调用方法【2.模板生成Word文档】:
/**
* 已提交状态的投保单初审通过通知【6】
* 附件3:保费支付通知书
* @param mailDTO
*/
public void BDYFH6(MailDTO mailDTO){
MailBean mailBean = MailBean.getMailBean();
Context context = new Context();
context.setVariable("productName", mailDTO.getProductName());
context.setVariable("orderNo", mailDTO.getOrderNo());
context.setVariable("user", mailDTO.getUserName());
List policyNo = mailDTO.getPolicyNo();
StringBuilder policyNos = new StringBuilder();
for (String pol:policyNo) {
policyNos.append(pol+". ");
}
context.setVariable("policyNo", policyNos);
context.setVariable("userdate", DateUtils.getCurrentTime());
String content = templateEngine.process("06emailTemplate", context);
mailBean.setSubject("已提交状态的投保单初审通过通知");
mailBean.setText(content);
//Word 模板拼接
WordAction wordAction = new WordAction();
//调用用户中心 根据省市区查询机构账户信息
ResponseEntity> eduZH = userClient.branchAccount(mailDTO.getAreaCode(), "edu", mailDTO.getProductCode());
GenericDataResponse body = eduZH.getBody();
if(null!=body){
JtBranchAccountVo data = body.getData();
List accountVoList = data.getAccountVoList();
for (AccountVo account:accountVoList) {
//户名
mailDTO.setAccount(account.getBankName());
//开户行
mailDTO.setBank(account.getBankAccountName());
//账号
mailDTO.setNumber(account.getBankAccountNo());
}
}
String s = wordAction.wordTest("1",mailDTO);
FileSystemResource file = new FileSystemResource(new File(s));
mailBean.setAttachmentFilename2("保费支付通知书.doc");
mailBean.setFile2(file);
mailBean.setEmail(mailDTO.getEmail());
mailUtil.sendMailAttachment(mailBean);
//删除附件
try {
java.io.File myDelFile = new java.io.File(s);
myDelFile.delete();
log.debug("删除文件成功==========》"+s);
} catch (Exception e) {
e.printStackTrace();
throw new BizException("删除文件失败");
}
}
小技巧:使用freemaker生成Word文档工具类
/**
* @Description: 生成Word工具类
* @author: xuxinku
* @Date: 2019/6/16 9:42
* @ModifiedDate:
* @Copyright:XX保险股份有限公司
*/
public class WordUtil {
/**
* @Desc:生成word文件
* @Author:xuxinke
* @Date:2019/6/16 9:42
* @param dataMap word中需要展示的动态数据,用map集合来保存
* @param templateName word模板名称,例如:06test.ftl
* @param filePath 文件生成的目标路径,例如:D:/wordFile/
* @param fileName 生成的文件名称,例如:test.doc
*/
@SuppressWarnings("unchecked")
public static String createWord(Map dataMap, String templateName, String filePath, String fileName){
try {
//创建配置实例
Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
//设置编码
configuration.setDefaultEncoding("UTF-8");
//ftl模板文件统一放至 com.lun.template 包下面
// D:\ideas\JTJBW\edu-svc\src\main\resources\templates
configuration.setClassForTemplateLoading(WordUtil.class,"/");
//获取模板
Template template = configuration.getTemplate(templateName);
//输出文件
File outFile = new File(filePath+ File.separator+fileName);
//如果输出目标文件夹不存在,则创建
if (!outFile.getParentFile().exists()){
outFile.getParentFile().mkdirs();
}
//将模板和数据模型合并生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
//生成文件
template.process(dataMap, out);
//关闭流
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
String WJ=filePath+fileName;
return WJ;
}
}
调用生成Word的方法
public String wordTest(String ftlType, MailDTO mailDTO){
/** 用于组装word页面需要的数据 */
Map dataMap = new HashMap();
dataMap.put("user",mailDTO.getUserName());
List policyNo = mailDTO.getPolicyNo();
StringBuilder policyNos = new StringBuilder();
for (String pol:policyNo) {
policyNos.append(pol+". ");
}
dataMap.put("policyNo",policyNos+"");
dataMap.put("orderNo",mailDTO.getOrderNo());
dataMap.put("premium",mailDTO.getPremium());
dataMap.put("account",mailDTO.getAccount());
dataMap.put("bank",mailDTO.getBank());
dataMap.put("number",mailDTO.getNumber());
dataMap.put("date", DateUtils.getCurrentTime());
dataMap.put("startDate",mailDTO.getStartDate());
String email = sdEmail(mailDTO.getRegion());
dataMap.put("region",mailDTO.getRegion());
dataMap.put("email",email);
//String filePath = "D:/JB/";
//String filePath =System.getProperty("java.io.tmpdir")+ File.separator;
String filePath =System.getProperties().getProperty("user.home")+ File.separator;
System.out.println("查看临时路径=======》"+filePath);
//文件唯一名称
String fileOnlyName = "保费支付通知.doc";
/** 生成word 数据包装,模板名,文件生成路径,生成的文件名*/
String WJ="";
if("1".equals(ftlType)){
//WJ = WordUtil.createWord(dataMap, "06test.ftl", filePath, fileOnlyName);
WJ = WordUtil.createWord(dataMap, "06ZF.ftl", filePath, fileOnlyName);
}else if("2".equals(ftlType)){
WJ = WordUtil.createWord(dataMap, "YN.ftl", filePath, fileOnlyName);
}else if("3".equals(ftlType)){
//WJ = WordUtil.createWord(dataMap, "SD.ftl", filePath, fileOnlyName);
WJ = WordUtil.createWord(dataMap, "SDZF.ftl", filePath, fileOnlyName);
}
return WJ;
}
ps:资源服务器下载的 需要转成字节数组:
/**
* 从输入流中获取字节数组
* @param inputStream
* @return
* @throws IOException
*/
public static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
接下来为在提供个小util 来校验邮箱是否正确:
/**
* 校验EMAIL格式,真为正确
*
* @author
* @date 2019-7-16
* @param email
* @return true 为格式正确 false 为格式错误
*/
public static boolean emailFormat(String email) {
boolean tag = true;
if (!email.matches("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+")) {
tag = false;
}
return tag;
}
纯手打 如果发现错误请指点一二