由于初次用SpringBoot的 JavaMailSender 插件发送邮件,在这个过程中遇到一些问题,我想把自己所遇到的技术点分享给大家,让你们在遇到此类问题时少走弯路,尽快的解决自己的问题!
好了、现在就开始介绍邮件发送的功能点。邮件风格一般分为三种格式:发送简单邮件、发送带附件的邮件、发送模板邮件。在该篇文章中,主要介绍带附件邮件以及模板邮件,其中包括 html转pdf,且html中嵌入图片。
首先需要这两个包,spring-boot-starter-mail:这个是主要负责邮件发送功能。spring-boot-starter-freemarker 这个是负责邮件模板功能。如果需要把html模板转换成PDF格式,需要引入 itextpdf、xmlworker、itext-asian包。
一:发送简单邮件
@Autowired
private JavaMailSender mailSender;//邮件插件
@Autowired
private FreeMarkerConfigurer freeMarker;// 邮件模板
public boolean sendSimpleMail() throws Exception {
MimeMessage message = null;
boolean flag = true;
try {
message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(“邮件发送者”);
helper.setTo(“邮件接收者”);
helper.setSubject(“邮件主题”);
helper.setText("内容");
mailSender.send(message);
} catch (Exception e) {
flag = false;
logger.error("系统异常邮件发送异常:{}", e);
e.printStackTrace();
}
return flag;
}
二:发送模板与带附件的邮件
public boolean sendDetectedMail(MailFileDto mailDto) throws Exception {
MimeMessage message = null;
boolean flag = true;
try {
String[] sendTo = {'张三','李四','王五'};//接受者可以有多个,以数组的形式传入参数
message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(“邮件发送者”);
helper.setTo(“邮件接收者”);
helper.setSubject(“邮件主题”);
// 邮件参数
Map<String, Object> model = new HashMap<String, Object>();
model.put("producttype", mailDto.getProductType());
model.put("warrantyType", mailDto.getWarrantyType());
//获取静态文件流资源
Resource resource = new ClassPathResource("images/logo.png");
model.put("logoImg", "data:image/png;base64," + Html2PdfUtil.img2Base64(resource));//对于模板中的静态图片、需要先把图片流转换Base64,才能带入到邮件中去
// 读取附件html模板:运单附件格式为PDF
Template attachmentTempl = freeMarker.getConfiguration().getTemplate("checkReport.html");
final String attachmentHtml = FreeMarkerTemplateUtils.processTemplateIntoString(attachmentTempl, model);
// 转换PDF格式的附件
final byte[] contents = Html2PdfUtil.buildPdf(attachmentHtml);//将html邮件模板转换成PDF
helper.addAttachment("diagnosticReport.pdf", new InputStreamSource() {
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(contents);
}
});
// PDF附件上传文件服务器
String filePath = upload2FileServer(mailDto.getRefNumber() + ".pdf", contents, mailDto.getFileServiceUrl());
model.put("downloadFilePath", filePath);
// 读取邮件 html 模板
Template template = freeMarker.getConfiguration().getTemplate("detected.html");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
helper.setText(html, true);
// 带有静态图片资源
//FileSystemResource file = new FileSystemResource(new File(fileSrc));//此方法项目打包发布后获取不到静态资源
helper.addInline("logo", resource);
// 开始发送
mailSender.send(message);
} catch (Exception e) {
flag = false;
logger.error("检测报告邮件发送异常:{}", e);
e.printStackTrace();
}
return flag;
}
/**
* 把Html转换pdf文件
*/
public static byte[] buildPdf(String ctx) throws DocumentException, IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
CssAppliers cssAppliers = new CssAppliersImpl();
cssAppliers.setChunkCssAplier(new MyChunkCssApplier());
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
DefaultTagProcessorFactory tpf=(DefaultTagProcessorFactory)Tags.getHtmlTagProcessorFactory();
tpf.addProcessor(Tag.IMG, ImageProcessor.class.getName());
htmlContext.setTagFactory(tpf);
CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
Pipeline<?> pipeline = new CssResolverPipeline(cssResolver,new HtmlPipeline(htmlContext, new PdfWriterPipeline(document,writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParser = new XMLParser(worker);
ByteArrayInputStream bais=new ByteArrayInputStream(ctx.getBytes());
xmlParser.parse(new InputStreamReader(bais));
xmlParser.flush();
document.close();
byte[] result=baos.toByteArray();
baos.flush();
baos.close();
return result;
}
/**
* 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
* @param imgpath
* @return
*/
public static String img2Base64(Resource resource) {
byte[] data = null;
// 读取图片字节数组
try {
InputStream inputStream = resource.getInputStream();
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return new String(Base64.encodeBase64(data));
}
邮件配置:
# JavaMailSender 邮件发送的配置
#spring.mail.host=smtp.exmail.qq.com
#spring.mail.username=邮箱名
#spring.mail.password=密码
#spring.mail.properties.mail.smtp.auth=true
#spring.mail.properties.mail.smtp.starttls.enable=true
#spring.mail.properties.mail.smtp.starttls.required=true
#如果服务器25端口被禁用,请用以下配置
spring.mail.host=smtp.exmail.qq.com
spring.mail.port=465
spring.mail.username=邮箱名
spring.mail.password=密码
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.starttls.enable = true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.enable = true