依賴
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
package com.rjj.demo.tools.mail; import com.jfinal.log.Log; import com.sun.mail.util.MailSSLSocketFactory; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.*; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; /** ** 郵件 * * 1.普通文本 sendText html消息 sendHtml * * 2.圖片 * * 3.附件 sendFile * * 4.文本+圖片 sendTextPhoto * * 5.圖片文本附件 sendTextPhotoFile * * 6.抄送,密送 * * 7.羣發【普通發送的時候把發送地址拼接字符串a,b.c】 */ public class MailUtilMe { private Log logger = Log.getLog(MailUtil.class); //發件箱 private String fromEmail = "215060580@qq.com"; //發件箱別名 private String personel = "淡淡人生過"; //發件箱密碼 private String password = "rylihxxxxxxzcajb"; //端口 private String port = "465"; //主機地址 private String host = "smtp.qq.com"; //收件人郵箱 private String toEmail = "253481340@qq.com"; //主題 private String subject ="淡淡人生過的第一份郵件"; //獲取基本配置,這種可能會報錯 /** * 會報錯javax.net.ssl.SSLHandshakeException: * sun.security.validator.ValidatorException: * PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: * unable to find valid certification path to requested target * * 錯誤很簡單,就是證書路徑無效,網上有人說使用代碼下載證書到本地jre證書庫中, * 或者直接導入此證書到jre證書;確實能夠;可是咱們能夠在代碼中信任此站點證書 * @return */ public Properties getProperties(){ Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; Properties props = System.getProperties(); props.setProperty("mail.host", host);//主機 props.put("mail.transport.protocol", "smtp");//連接協議 props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY); props.setProperty("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.port", port); props.setProperty("mail.smtp.socketFactory.port", port); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable","true");//開啓ssl加密 props.put("mail.debug", "true");// 設置是否顯示debug信息 true 會在控制檯顯示相關信息 return props; } /** * 基本不會出現問題 * @return */ public Properties getProp(){ Properties props = System.getProperties(); props.setProperty("mail.host", host);//主機地址 props.put("mail.transport.protocol", "smtp");//連接協議 props.setProperty("mail.smtp.port", port);//端口 props.put("mail.smtp.auth", "true"); // 容許smtp校驗 MailSSLSocketFactory sf = null; try { sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); } catch (GeneralSecurityException e) { logger.info("error", e); } props.put("mail.smtp.ssl.enable", "true");//開啓ssl加密 props.put("mail.smtp.ssl.socketFactory", sf); props.put("mail.smtp.socketFactory.fallback", "false"); props.put("mail.smtp.socketFactory.port", port); props.put("mail.debug", "true");// 設置是否顯示debug信息 true 會在控制檯顯示相關信息 return props; } /** * 獲取session */ public Session getSession(){ Properties prop = getProp(); Session session = Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(fromEmail,password); } }); return session; } public MimeMessage getMineMessage() { Session session = getSession(); // 建立默認的 MimeMessage 對象 MimeMessage message = new MimeMessage(session); try { // Set From: 頭部頭字段,設置了默認名稱,就會顯示發送人爲 "淡淡人生過" message.setFrom(new InternetAddress(fromEmail,personel)); /** * Set To: 頭部頭字段 * * Message.RecipientType.TO 普通發送 * Message.RecipientType.CC 抄送 * Message.RecipientType.BCC 密送 */ //給一我的發送郵件 message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail)); //給多我的發送郵件 //message.addRecipients(Message.RecipientType.TO,new Address[]{new InternetAddress(toEmail),new InternetAddress(toEmail)}); //message.addRecipients(Message.RecipientType.CC,new Address[]{new InternetAddress(toEmail)}); //message.addRecipients(Message.RecipientType.BCC,new Address[]{new InternetAddress(toEmail)}); // Set Subject: 頭部頭字段 message.setSubject(subject,"UTF-8"); //設置郵件的發送時間 message.setSentDate(new Date()); } catch (MessagingException e) { logger.info("1出現異常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("2出現異常:" + e.getMessage()); } return message; } /** * 發送郵件 * * 普通文本消息 */ public void sendText(String content) { MimeMessage message = getMineMessage(); // 設置消息體 try { message.setText(content); Transport.send(message); } catch (MessagingException e) { logger.info("設置文本內容出現異常:" + e.getMessage()); } } /** * 發送郵件 * * html消息 */ public void sendHtml(String content){ MimeMessage message = getMineMessage(); try { message.setContent(content,"text/html;charset=UTF-8"); Transport.send(message); } catch (MessagingException e) { logger.info("設置html內容出現異常:" + e.getMessage()); } } /** * 發送帶附件的郵件 */ public void sendFile(String content, String pathFileName){ MimeMessage message = getMineMessage(); // 建立多重消息 Multipart multipart = new MimeMultipart(); try { // 建立消息部分 BodyPart messageBodyPart = new MimeBodyPart(); // 消息,這裏的消息不發送也是能夠的 // messageBodyPart.setText(content); messageBodyPart.setContent(content, "text/html; charset=utf-8"); // 設置文本消息部分 multipart.addBodyPart(messageBodyPart); // 附件部分 messageBodyPart = new MimeBodyPart(); //獲取文件 DataSource source = new FileDataSource(pathFileName); messageBodyPart.setDataHandler(new DataHandler(source)); //設置文件名稱 messageBodyPart.setFileName(MimeUtility.encodeText(source.getName())); //添加到多重消息容器中 multipart.addBodyPart(messageBodyPart); // 發送完整消息 message.setContent(multipart); // 發送消息 Transport.send(message); } catch (MessagingException e) { logger.info("發送附件郵件出現異常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("文件名稱編碼異常:" + e.getMessage()); } } /** * 多文件下載 * @param content 信息 * @param pathFileName 多個附件的路徑 */ public void sendFileList(String content, List<String> pathFileName){ MimeMessage message = getMineMessage(); try { // 建立多重消息 Multipart multipart = new MimeMultipart(); //消息 BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(content,"text/html; charset=utf-8"); multipart.addBodyPart(messageBodyPart); for (String filePath : pathFileName) { // 附件部分 // 建立消息部分 messageBodyPart = new MimeBodyPart(); //獲取文件 DataSource source = new FileDataSource(filePath); messageBodyPart.setDataHandler(new DataHandler(source)); //設置文件名稱 messageBodyPart.setFileName(MimeUtility.encodeText(source.getName())); //添加到多重消息容器中 multipart.addBodyPart(messageBodyPart); } // 發送完整消息 message.setContent(multipart); // 發送消息 Transport.send(message); } catch (MessagingException e) { logger.info("發送附件郵件出現異常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("文件名稱編碼異常:" + e.getMessage()); } } /** * 發送圖片和附件郵件 */ public void sendTextPhotoFile(){ String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MimeMessage message = getMineMessage(); try { // 1.建立圖片"節點" MimeBodyPart image = new MimeBodyPart(); // 讀取本地文件 DataHandler dh = new DataHandler(new FileDataSource(pathName)); // 將圖片數據添加到"節點" image.setDataHandler(dh); // 爲"節點"設置一個惟一編號(在文本"節點"將引用該ID) image.setContentID("mailTestPic"); // 2. 建立文本"節點" MimeBodyPart text = new MimeBodyPart(); // 這裏添加圖片的方式是將整個圖片包含到郵件內容中, 實際上也能夠以 http 連接的形式添加網絡圖片 /** * 這裏在img標籤中src屬性中添加了cid:mailTestPic 其實就是把圖片和我發送的圖片關聯起來了,點擊圖片就會跳到個人路徑所在的地址 這裏使用a標籤包裹了,個人圖片,發送的內容其實時html的,因此有些標籤不顯示,其實一html的標籤 */ text.setContent( "這是一張圖片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要點擊圖片跳到的地址 "<img src='cid:mailTestPic'/>" + //圖片,能夠寫網絡圖片的地址 "</a>" , "text/html;charset=UTF-8");//html,使用utf-8,識別 // 3. (文本+圖片)設置 文本 和 圖片"節點"的關係(將 文本 和 圖片"節點"合成一個混合"節點") MimeMultipart mm_text_image = new MimeMultipart(); mm_text_image.addBodyPart(text); mm_text_image.addBodyPart(image); mm_text_image.setSubType("related"); // 關聯關係 // 4. 將 文本+圖片 的混合"節點"封裝成一個普通"節點" // 最終添加到郵件的 Content 是由多個 BodyPart 組成的 Multipart, 因此咱們須要的是 BodyPart, // 上面的 mailTestPic 並不是 BodyPart, 全部要把 mm_text_image 封裝成一個 BodyPart MimeBodyPart text_image = new MimeBodyPart(); text_image.setContent(mm_text_image); // 5. 建立附件"節點" MimeBodyPart attachment = new MimeBodyPart(); // 讀取本地文件 DataHandler dh2 = new DataHandler(new FileDataSource(pathName)); // 將附件數據添加到"節點" attachment.setDataHandler(dh2); // 設置附件的文件名(須要編碼) attachment.setFileName(MimeUtility.encodeText(dh2.getName())); // 6. 設置(文本+圖片)和 附件 的關係(合成一個大的混合"節點" / Multipart ) MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text_image); mm.addBodyPart(attachment); // 若是有多個附件,能夠建立多個屢次添加 mm.setSubType("mixed"); // 混合關係 // 7. 設置整個郵件的關係(將最終的混合"節點"做爲郵件的內容添加到郵件對象) message.setContent(mm); Transport.send(message); } catch (MessagingException e) { logger.info("圖片文本文件消息異常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } public void sendTextPhoto(){ String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MimeMessage message = getMineMessage(); try { // 1.建立圖片"節點" MimeBodyPart image = new MimeBodyPart(); // 讀取本地文件 DataHandler dh = new DataHandler(new FileDataSource(pathName)); // 將圖片數據添加到"節點" image.setDataHandler(dh); // 爲"節點"設置一個惟一編號(在文本"節點"將引用該ID) image.setContentID("mailTestPic"); // 2. 建立文本"節點" MimeBodyPart text = new MimeBodyPart(); // 這裏添加圖片的方式是將整個圖片包含到郵件內容中, 實際上也能夠以 http 連接的形式添加網絡圖片 /** * 這裏在img標籤中src屬性中添加了cid:mailTestPic 其實就是把圖片和我發送的圖片關聯起來了,點擊圖片就會跳到個人路徑所在的地址 這裏使用a標籤包裹了,個人圖片,發送的內容其實時html的,因此有些標籤不顯示,其實一html的標籤 */ text.setContent( "這是一張圖片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要點擊圖片跳到的地址 "<img src='cid:mailTestPic'/>" + //圖片,能夠寫網絡圖片的地址 "</a>" , "text/html;charset=UTF-8");//html,使用utf-8,識別 // 3. (文本+圖片)設置 文本 和 圖片"節點"的關係(將 文本 和 圖片"節點"合成一個混合"節點") MimeMultipart mm_text_image = new MimeMultipart(); mm_text_image.addBodyPart(text); mm_text_image.addBodyPart(image); /** * 郵件體包含郵件的內容,它的類型由郵件頭的「Content-Type」域指出。常見的簡單類型有text/plain(純文本)和text/html(超文本)。有時也會出現的multipart類型,是MIME郵件的精髓。郵件體被分爲多個段,每一個段又包含段頭和段體兩部分,這兩部分之間也以空行分隔。常見的multipart類型有三種:multipart/mixed, multipart/related和multipart/alternative。 * * multipart/mixed:附件。 * * multipart/related:內嵌資源。 * * multipart/alternative:純文本與超文本共存。 */ mm_text_image.setSubType("mixed"); // 關聯關係,這裏圖片至關於附件了,只是在正文內容中一img標籤顯示出來了 // 7. 設置整個郵件的關係(將最終的混合"節點"做爲郵件的內容添加到郵件對象) message.setContent(mm_text_image); Transport.send(message); } catch (MessagingException e) { logger.info("發送文本圖片消息出現異常:" + e.getMessage()); } } public static void main(String[] args) { String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MailUtilMe m = new MailUtilMe(); //m.sendTextPhotoFile(); //m.sendText("a"); //m.sendHtml("<b>你好</b>"); // m.sendFile("劉亦菲哦",pathName); // m.sendTextPhoto(); List<String> list = new ArrayList<>(2); list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg"); list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg"); m.sendFileList("劉亦菲",list); } }