本文主要是介绍线程池异步发送邮件之MimeMessageHelper邮件发送支持自定义发送人/图片/附件/多个接收人/抄送人/暗送人,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
项目中要发送邮件,写个工具类,小项目,并发量不高,但是要求:
1.发件人是163邮箱或qq邮箱
2.支持多个接收人/抄送人/暗送人
3.支持正文中放图片
4.支持附件
5.线程池异步处理
6.发送异常时,调用开发员自定义的异常处理类
使用原生的java的mail.jar的API开发,需要自己调用组装很多API,MimeMessageHelper帮助类进行简化了很多步骤,用起来挺不错的。由于项目使用了spring boot,所以在pom.xml中只需添加
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
即可。
因为邮件发送有时耗时较长,所以代码中使用了线程池异步发送。下面先贴代码,再说需要注意的事项。
异常接口,当邮件发送失败,需要做额外处理时,开发员实现该接口。
package com.nanhe.building.util;import com.alibaba.fastjson.JSONObject;/*** 邮件发送异常处理* @author Jfei**/
public interface MailSendExceptionHandler {/*** 当邮件发送出现异常时,调用此方法* @param e 异常类* @param params 调用邮件工具类发送是传的参数,便于日志记录跟踪*/void doForException(Exception e,JSONObject params);
}
工具类
package com.nanhe.building.util;import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;import com.alibaba.fastjson.JSONObject;/*** 邮件发送(注意发送人的邮箱必须设置开通POP3/SMTP/IMAP,否则无法发送)* @author Jfei**/
public class MailUtil {/*** 线程池,最多同时3个线程在运行,其他的排队等候*/private static ExecutorService executor = Executors.newFixedThreadPool(3);/*** 发送邮件(注意发送人的邮箱必须设置开通POP3/SMTP/IMAP,否则无法发送)* @param sendUserAccount 发送人email账号(163或者qq邮箱) (必填)* @param sendUserPassword 发送人email的授权码(必填)* @param sendUserNickName 发送人的昵称* @param receiveUsers 接收人 (必填)* @param copyUsers 抄送人* @param darkUsers 暗送人* @param title 标题 (必填)* @param text 文本* @param bodyImgs 正文图片* @param attachDocs 附件* @param exceptionHandler 邮件发送异常时,调用处理类处理*/public static void sendMail(String sendUserAccount,String sendUserPassword,String sendUserNickName,String[] receiveUsers,String[] copyUsers,String[] darkUsers,String title,String text,File[] bodyImgs,File[] attachDocs,MailSendExceptionHandler exceptionHandler){MailThread mail = new MailThread(sendUserAccount, sendUserPassword, sendUserNickName, receiveUsers, copyUsers, darkUsers, title, text, bodyImgs, attachDocs,exceptionHandler);executor.execute(mail);executor.shutdown();}private static class MailThread extends Thread{private String sendUserAccount;private String sendUserPassword;private String sendUserNickName;private String[] receiveUsers;private String[] copyUsers;private String[] darkUsers;private String title;private String text;private File[] bodyImgs;private File[] attachDocs;private MailSendExceptionHandler exceptionHandler;private JSONObject params;//参数集合public MailThread(String sendUserAccount, String sendUserPassword,String sendUserNickName, String[] receiveUsers,String[] copyUsers, String[] darkUsers, String title,String text, File[] bodyImgs,File[] attachDocs,MailSendExceptionHandler exceptionHandler) {super();this.sendUserAccount = sendUserAccount;this.sendUserPassword = sendUserPassword;this.sendUserNickName = sendUserNickName;this.receiveUsers = receiveUsers;this.copyUsers = copyUsers;this.darkUsers = darkUsers;this.text = text;this.title = title;this.bodyImgs = bodyImgs;this.attachDocs = attachDocs;this.exceptionHandler = exceptionHandler;setParams();}private void setParams(){params = new JSONObject();params.put("sendUserAccount", sendUserAccount);params.put("sendUserPassword", sendUserPassword);params.put("sendUserNickName", sendUserNickName);params.put("receiveUsers", receiveUsers);params.put("copyUsers", copyUsers);params.put("darkUsers", darkUsers);params.put("title", title);params.put("text", text);if(bodyImgs != null && bodyImgs.length > 0){List<String> list = new ArrayList<String>();for(File f : bodyImgs){list.add(f.getName());}params.put("bodyImgs", list);}if(attachDocs != null && attachDocs.length > 0){List<String> list = new ArrayList<String>();for(File f : attachDocs){list.add(f.getName());}params.put("attachDocs", list);}}public void run(){long startTime = System.currentTimeMillis();try {//获取邮件发送实例JavaMailSenderImpl mailSender = getJavaMailSenderImpl(sendUserAccount, sendUserPassword);//创建邮件帮助类MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true,"UTF-8");//必须true//设置邮件内容setMailContent(messageHelper, title, text, bodyImgs, attachDocs);//设置发送人setSenderUser(messageHelper, sendUserAccount,sendUserNickName);//设置接收人setReceiveUsers(messageHelper, receiveUsers, copyUsers, darkUsers);//发送mailSender.send(mimeMessage);} catch (Exception e) {//邮件发送失败,可以将发送失败日志记录到数据库进行相关处理e.printStackTrace();if(this.exceptionHandler != null){this.exceptionHandler.doForException(e, params);}}long endTime = System.currentTimeMillis();String t = ((endTime-startTime)/(60*1000))+" 分 " + (((endTime -startTime)/1000.0)%60) + "秒";System.out.println("邮件发送耗时:" + t);}private JavaMailSenderImpl getJavaMailSenderImpl(String sendUserAccount,String sendUserPassword){//连接邮件服务器的参数配置Properties props = new Properties();//开启tlsprops.setProperty("mail.smtp.auth","true");props.setProperty("mail.smtp.ssl.enable", "true");// props.setProperty("smtp.starttls.required", "true");JavaMailSenderImpl impl = new JavaMailSenderImpl();impl.setHost(sendUserAccount.endsWith("163.com") ? "smtp.163.com":"smtp.qq.com");impl.setUsername(sendUserAccount);impl.setPassword(sendUserPassword);impl.setPort(465);impl.setDefaultEncoding("UTF-8");impl.setProtocol("smtp");impl.setJavaMailProperties(props);return impl;}/*** 设置邮件内容* @param help* @param title* @param plainText* @param htmlText* @param bodyImgs* @param attachDocs* @throws MessagingException* @throws UnsupportedEncodingException */private void setMailContent(MimeMessageHelper help,String title,String text,File[] bodyImgs,File[] attachDocs) throws MessagingException, UnsupportedEncodingException {//设置标题help.setSubject(title);//设置文本内容StringBuffer s = new StringBuffer("<html><body>");s.append(text );if(bodyImgs != null){for(int i = 0;i<bodyImgs.length;i++){s.append("<img src='cid:pic"+i+"' />");}}s.append("</body></html>");help.setText(s.toString(), true);//展示在正文的图片if(bodyImgs != null && bodyImgs.length > 0){for(int i = 0;i<bodyImgs.length;i++){help.addInline("pic"+i, bodyImgs[i]);}}//添加附件if(attachDocs != null && attachDocs.length > 0){for(File file : attachDocs){//解决附件中文乱码help.addAttachment(MimeUtility.encodeWord(file.getName()), file);}}}/*** 设置接收人,抄送人,暗送人* @param help* @param receiveUsers 接收人* @param copyUsers 抄送人* @param darkUsers 暗送人* @throws MessagingException*/private void setReceiveUsers(MimeMessageHelper help,String[] receiveUsers,String[] copyUsers,String[] darkUsers) throws MessagingException{if(receiveUsers != null){help.setTo(receiveUsers);}if(copyUsers != null && copyUsers.length > 0){help.setCc(copyUsers);}if(darkUsers != null && darkUsers.length > 0){help.setBcc(darkUsers);}}/*** 设置发送人* @param help* @param senderAccount 邮箱账号* @param userName 昵称* @throws MessagingException* @throws UnsupportedEncodingException */private void setSenderUser(MimeMessageHelper help,String senderAccount,String userName) throws MessagingException, UnsupportedEncodingException{if(userName != null){help.setFrom(senderAccount,userName);}else{help.setFrom(senderAccount);}}}/*** 测试* @param args*/public static void main(String[] args) {
// String sendUserAccount = "XXX@163.com";
// String sendUserPassword = "XXXX";//授权码String sendUserAccount = "XXXX@qq.com";String sendUserPassword = "zhnbgndydwuxbjdg";String sendUserNickName = "XXXX";String[] receiveUsers =new String[]{ "XXXX@163.com"};String[] copyUsers = new String[]{"XXXX@qq.com"};String[] darkUsers = new String[]{"XXXX@qq.com"};String title = "诗酒人生";String text = "落魄江南载酒行,楚腰肠断掌中轻。十年一觉扬州梦,赢得青楼薄幸名。";File[] bodyImgs = new File[]{new File("e:/1.jpg"),new File("e:/2.jpg")};
// File[] bodyImgs = new File[]{new File("e:/1.jpg")};
// File[] bodyImgs = null;//文件名不要出现空格File[] attachDocs = new File[]{new File("e:/文档2.docx"),new File("e:/文档.docx")};
// File[] attachDocs = null;sendMail(sendUserAccount, sendUserPassword, sendUserNickName, receiveUsers, copyUsers, darkUsers, title, text, bodyImgs, attachDocs,null);System.out.println("已异步发送。。。");}
}
注意事项:
1.发送人的邮箱必须开通了SMTP服务,并把授权码记下
163授权
如果忘记了,可以在“客户端授权密码”通过短信找回。
qq授权码
在“设置”“账户”中找,qq的授权码是自动生成的,最好记下来。
2.如果发送人是qq邮箱的,则没遇到什么问题,但是如果是163邮箱,则经常出现554 DT异常。网上找到的解决方案是:
(1)把邮件也抄送一份给发件人自己(经测试,没用)
(2)在163的“设置”->“发垃圾/黑白名单”设置里,白名单添加上“smtp.163.com”,以及自己服务器的公网IP(直接百度IP,就可以看到自己的公网IP是多少了)(经测试,不稳定,仍然会有554 DT)
这篇关于线程池异步发送邮件之MimeMessageHelper邮件发送支持自定义发送人/图片/附件/多个接收人/抄送人/暗送人的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!