由於初次用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