用程序發郵件首先須要一個smtp服務器,html
雖說網上也有自建服務器的教程,可是因爲工程量大,java
還要兼容各大郵箱廠商,有可能發送失敗或被歸爲垃圾郵件。apache
因此不推薦自建smtp服務器實現。安全
推薦是有2種方法來實現 第三方郵箱發郵件服務器
一、買相似阿里雲的smtp資源包(阿里雲 1000條 / 2元)session
二、申請一個騰訊、網易163的郵箱,開通smtp服務端口,藉由他們的服務器來轉發。socket
(其中部分第三方郵箱能夠實現用本身的域名來接發郵件,例如service@baidu.com)maven
本文中介紹的是第二種方法,用騰訊企業郵箱爲例ide
參考借鑑的大神的原文地址:http://www.javashuo.com/article/p-tdqqwvum-gs.html工具
這裏重點只說明一下,騰訊企業郵箱 + javamail 來實現發郵件,代碼的部分。
其餘郵箱,例如我的的qq郵箱 163郵箱也能夠用這個方法實現,申請和設置方法借鑑百度吧
補充一下!騰訊企業郵箱和qq郵箱方法有幾個不一樣,我在末尾加了qq郵箱的方案
正文開始
先說騰訊企業郵箱
maven
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency>
另外我用到了一個 StringUtils.isNotBlank() 方法 能夠選擇引入如下maven依賴,也能夠改寫成 xxx != null && !"".equals(xxx) 等價的代碼
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency>
java 工具類
須要把 用戶名、密碼、發件人別名 等參數填成你本身申請的
package com.gemini.common.utils; import com.sun.mail.util.MailSSLSocketFactory; import org.apache.commons.lang.StringUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.util.Date; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; public class EmailUtils { // 騰訊企業郵箱 也能夠換成別家的 private static final String protocol = "smtp";// 協議 private static final String host = "smtp.exmail.qq.com";// 地址 private static final String port = "465";// 端口 private static final String account = "用戶名";// 用戶名 private static final String pass = "密碼";// 密碼 private static final String personal = "發件人別名(選填)";// 發件人別名,不須要設爲空串或null // 權限認證 static class MyAuthenricator extends Authenticator { String u = null; String p = null; public MyAuthenricator(String u, String p) { this.u = u; this.p = p; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(u, p); } } /** * 發送郵件工具方法 * * @param recipients 收件人 * @param subject 主題 * @param content 內容 * @param fileStr 附件路徑 * @return true/false 發送成功 */ public static boolean sendEmail(String recipients, String subject, String content, String fileStr) { Properties prop = new Properties(); //協議 prop.setProperty("mail.transport.protocol", protocol); //服務器 prop.setProperty("mail.smtp.host", host); //端口 prop.setProperty("mail.smtp.port", port); //使用smtp身份驗證 prop.setProperty("mail.smtp.auth", "true"); //使用SSL,企業郵箱必需! //開啓安全協議 MailSSLSocketFactory mailSSLSocketFactory = null; try { mailSSLSocketFactory = new MailSSLSocketFactory(); mailSSLSocketFactory.setTrustAllHosts(true); } catch (GeneralSecurityException e1) { e1.printStackTrace(); } prop.put("mail.smtp.ssl.enable", "true"); prop.put("mail.smtp.ssl.socketFactory", mailSSLSocketFactory); Session session = Session.getDefaultInstance(prop, new MyAuthenricator(account, pass)); session.setDebug(true); MimeMessage mimeMessage = new MimeMessage(session); try { //發件人 if (StringUtils.isNotBlank(personal)) mimeMessage.setFrom(new InternetAddress(account, personal));//能夠設置發件人的別名 else mimeMessage.setFrom(new InternetAddress(account));//若是不須要就省略 //收件人 mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(recipients)); //主題 mimeMessage.setSubject(subject); //時間 mimeMessage.setSentDate(new Date()); //容器類,能夠包含多個MimeBodyPart對象 Multipart mp = new MimeMultipart(); //MimeBodyPart能夠包裝文本,圖片,附件 MimeBodyPart body = new MimeBodyPart(); //HTML正文 body.setContent(content, "text/html; charset=UTF-8"); mp.addBodyPart(body); //添加圖片&附件 if(StringUtils.isNotBlank(fileStr)){ body = new MimeBodyPart(); body.attachFile(fileStr); mp.addBodyPart(body); } //設置郵件內容 mimeMessage.setContent(mp); //僅僅發送文本 //mimeMessage.setText(content); mimeMessage.saveChanges(); Transport.send(mimeMessage); // 發送成功 return true; } catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } public static void main(String[] args) { sendEmail("你的郵箱地址","test","test",null); } }
關於上述方案,適用於通常的郵箱申請(騰訊企業郵箱、網易郵箱),但不適用於qq郵箱,緣由是qq郵箱目前只接受受權碼方案登陸,官方的解釋是「舒適提示:在第三方登陸QQ郵箱,可能存在郵件泄露風險,甚至危害Apple ID安全,建議使用QQ郵箱手機版登陸。 繼續獲取受權碼登陸第三方客戶端郵箱 。」
使用上述方法登陸qq郵箱會遇到報錯
javax.mail.AuthenticationFailedException: 535 Error: ÇëʹÓÃÊÚȨÂëµÇ¼¡£ÏêÇéÇë¿´: http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
如圖
意思就是不支持直接用默認密碼登陸,必須去申請一個受權碼做爲密碼登陸
其實流程和工具類都同樣就重點說 2個不同的地方
獲取方式 [登陸郵箱] - [設置] - [帳戶] ,而後以下圖找到POP3/SMTP服務的下面,有一句舒適提示 先點 [生成受權碼] ,再根據提示獲取到受權碼。
受權碼就是javamail裏的password
騰訊企業郵箱的host是
private static final String host = "smtp.exmail.qq.com";// 地址
普通qq郵箱的host是
private static final String host = "smtp.qq.com";// 地址
修改這兩個地方便可適用於我的普通的qq郵箱
最終效果以下
另外本文也發佈在了個人我的博客: https://zzzmh.cn/single?id=49