郵件發送器
/** * 郵件發送器 * * @author Zebe */ public class MailSender implements Runnable { /** * 收件人 */ private String to; /** * 收件人名稱 */ private String toName; /** * 主題 */ private String subject; /** * 內容 */ private String content; /** * 附件列表 */ private List<String> attachFileList; /** * 構造器 * @param to 收件人 * @param subject 主題 * @param content 內容 */ public MailSender(String to,String toName, String subject, String content) { this.to = to; this.toName = toName; this.subject = subject; this.content = content; } /** * 構造器 * @param to 收件人 * @param subject 主題 * @param content 內容 * @param attachFileList 附件列表 */ public MailSender(String to, String toName,String subject, String content, List<String> attachFileList) { this(to, toName, subject, content); this.attachFileList = attachFileList; } @Override public void run() { new SendEmailUtil(to,toName, subject, content, attachFileList).send(); } }
郵件發送線程池
/** * 郵件發送線程池 * * @author Zebe */ public class MailSenderPool { /** * 郵件發送器線程數量 */ private static int SENDER_TOTAL = 10; /** * 線程工廠(生產環境中建議使用帶命名參數的線程工廠) */ private static ThreadFactory threadFactory = Executors.defaultThreadFactory(); /** * 線程池執行器(采用了Spring提供的CustomizableThreadFactory,如果不需要請使用默認線程工廠) */ private static ExecutorService executor = new ThreadPoolExecutor(SENDER_TOTAL, 200, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy()); /** * 內部靜態實例 */ private static class Inner { private static MailSenderPool instance = new MailSenderPool(); } /** * 獲取實例 * * @return 返回郵件發送線程池實例 */ public static MailSenderPool getInstance() { return Inner.instance; } /** * 通過線程發送 * * @param sender 郵件發送器 * @return 返回自身 */ public MailSenderPool sendByThread(MailSender sender) { executor.execute(sender); return getInstance(); } /** * 關閉線程池 */ public void shutDown() { executor.shutdown(); } }
郵件發送工具類
/** * 郵件發送工具類。 * 以下郵件中的配置參數,請在實際環境中,根據需要采取合適的配置方式。 * 發送郵件依賴 com.sun.mail(1.6.1) 包、javax.mail(1.5.0-b01) 包。 * 如果使用 Idea 運行,請將這兩個包(可以直接到Maven目錄下面去找)添加到項目的 Libraries 里面(快捷鍵:Ctrl + Alt + Shift + S) * * @author Zebe */ public class SendEmailUtil { /** * 發件人別名(可以為空) */ private final static String fromAliasName = "****"; /** * 登錄用戶名 */ private String ACCOUNT; /** * 登錄密碼 */ private String PASSWORD; /** * 郵件服務器地址 */ //QQ企業郵箱:smtp.exmail.qq.com //網易企業郵箱:smtphz.qiye.163.com private String HOST; /** * 發信端口 */ //QQ企業郵箱:465 //網易企業郵箱:994 private String PORT; /** * 發信協議 */ private final static String PROTOCOL = "ssl"; /** * 收件人 */ private String to; /** * 收件人名稱 */ private String toName; /** * 主題 */ private String subject; /** * 內容 */ private String content; /** * 附件列表(可以為空) */ private List<String> attachFileList; /** * 構造器 * * @param attachFileList 附件列表 */ public SendEmailUtil(MailTemplate mailTemplate, List<String> attachFileList) { this.to = mailTemplate.getTo(); this.toName = mailTemplate.getToName(); this.subject = mailTemplate.getSubject(); this.content = mailTemplate.getContent(); this.attachFileList = attachFileList; this.ACCOUNT = mailTemplate.getAccount(); this.PASSWORD = mailTemplate.getPassword(); switch (mailTemplate.getSendType()) { case "qq": this.HOST = "smtp.exmail.qq.com"; this.PORT = "465"; break; case "163": this.HOST = "smtp.ym.163.com"; this.PORT = "994"; break; } } /** * 認證信息 */ static class MyAuthenticator extends Authenticator { /** * 用戶名 */ String username = null; /** * 密碼 */ String password = null; /** * 構造器 * * @param username 用戶名 * @param password 密碼 */ public MyAuthenticator(String username, String password) { this.username = username; this.password = password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } } /** * 發送郵件 */ public boolean send() { // 設置郵件屬性 Properties prop = new Properties(); prop.setProperty("mail.transport.protocol", PROTOCOL); prop.setProperty("mail.smtp.host", HOST); prop.setProperty("mail.smtp.port", PORT); prop.setProperty("mail.smtp.auth", "true"); MailSSLSocketFactory sslSocketFactory = null; try { sslSocketFactory = new MailSSLSocketFactory(); sslSocketFactory.setTrustAllHosts(true); } catch (GeneralSecurityException e1) { e1.printStackTrace(); } if (sslSocketFactory == null) { System.err.println("開啟 MailSSLSocketFactory 失敗"); } else { prop.put("mail.smtp.ssl.enable", "true"); prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory); // 創建郵件會話(注意,如果要在一個進程中切換多個郵箱賬號發信,應該用 Session.getInstance) Session session = Session.getDefaultInstance(prop, new MyAuthenticator(ACCOUNT, PASSWORD)); // 開啟調試模式(生產環境中請不要開啟此項) session.setDebug(true); try { MimeMessage mimeMessage = new MimeMessage(session); // 設置發件人別名(如果未設置別名就默認為發件人郵箱) mimeMessage.setFrom(new InternetAddress(ACCOUNT, fromAliasName)); // 設置主題和收件人、發信時間等信息 mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to, toName)); mimeMessage.setSubject(subject); mimeMessage.setSentDate(new Date()); //圖片 MimeBodyPart img = new MimeBodyPart(); DataHandler dh = new DataHandler(new FileDataSource("src/main/resources/2.jpg"));//圖片路徑 img.setDataHandler(dh); img.setContentID("img"); //正文 MimeBodyPart text = new MimeBodyPart(); text.setContent("這里正文內容 for img<img src='cid:img'><br/>", "text/html;charset=utf-8"); //注意編碼問題 //描述數據關系 MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text); mm.addBodyPart(img); mm.setSubType("related"); //圖片-文本--復合--轉普通節點 MimeBodyPart tex_image_tPart=new MimeBodyPart(); tex_image_tPart.setContent(mm); // 如果有附件信息,則添加附件 if (!attachFileList.isEmpty()) { Multipart multipart = new MimeMultipart(); MimeBodyPart body = new MimeBodyPart(); body.setContent(content, "text/html; charset=UTF-8"); multipart.addBodyPart(body); // 添加所有附件(添加時判斷文件是否存在) for (String filePath : attachFileList) { if (Files.exists(Paths.get(filePath))) { MimeBodyPart tempBodyPart = new MimeBodyPart(); tempBodyPart.attachFile(filePath); multipart.addBodyPart(tempBodyPart); } } mimeMessage.setContent(multipart); } else { // Multipart multipart = new MimeMultipart(); // MimeBodyPart body = new MimeBodyPart(); // body.setContent(mm, "text/html; charset=UTF-8"); // multipart.addBodyPart(body); MimeMultipart mimeMultipart1=new MimeMultipart(); mimeMultipart1.addBodyPart(tex_image_tPart); mimeMultipart1.setSubType("mixd");//混合關系 mimeMessage.setContent(mimeMultipart1, "text/html; charset=UTF-8"); //mimeMessage.setText(content); } // 開始發信 mimeMessage.saveChanges(); Transport.send(mimeMessage); return true; } catch (MessagingException | IOException e) { e.printStackTrace(); return false; } } return false; } }
示例
public static void main(String[] args) { try { int num; // 通過線程池發送郵件 MailSenderPool pool = MailSenderPool.getInstance(); for (num=1;num<=73;num++){ // 設置發信參數 final String toName = "我是" + num + "號"; final String to = "test" + num + "@***.com"; String subject = num + " 第一次發送測試郵件標題"; final String content = "<p style='color:red'>這是郵件內容正文。</p>"; // 設置附件路徑(注意:res 是項目根目錄下的一個文件夾) // final List<String> attachFileList = Arrays.asList("res/1.png", "res/1.pdf"); pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>())); subject = num + " 第二次發送測試郵件標題"; pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>())); } pool.shutDown(); }catch (Exception e){ System.out.println("錯誤: " + e); } }