昨天正好要用郵件發送的功能,順便看了下具體的實現,網上的版本不少,下面是我本身以爲高可用的一個版本,很是好用,並進行總結,優化了,你們能夠拿來直接使用哦。html
Java使用時添加相應的lib包:mail-1.4.7.jar,其餘版本的也行。總的來講,須要實現三個類(可是,爲了代碼結構的嚴謹性,咱們仍是寫完整些吧),你們能夠放在一個package包下,方便管理和使用。java
好了,閒話很少說,見代碼吧。服務器
(一)郵件內容實體類(大部分版本都差很少,有的參數未用到)session
package com.yoki.util.mail; import java.util.Properties; public class MailSenderInfo { // 發送郵件的服務器的IP和端口 private String mailServerHost; private String mailServerPort = "25"; // 郵件發送者的地址 private String fromAddress; // 郵件接收者的地址 private String toAddress; // 登錄郵件發送服務器的用戶名和密碼 private String userName; private String password; // 是否須要身份驗證 private boolean validate = false; // 郵件主題 private String subject; // 郵件的文本內容 private String content; // 郵件附件的文件名 private String[] attachFileNames; /** * 得到郵件會話屬性 */ public Properties getProperties() { Properties p = new Properties(); p.put("mail.smtp.host", this.mailServerHost); p.put("mail.smtp.port", this.mailServerPort); p.put("mail.smtp.auth", (this.validate) ? "true" : "false"); return p; } public String getMailServerHost() { return this.mailServerHost; } public void setMailServerHost(String mailServerHost) { this.mailServerHost = mailServerHost; } public String getMailServerPort() { return this.mailServerPort; } public void setMailServerPort(String mailServerPort) { this.mailServerPort = mailServerPort; } public boolean isValidate() { return this.validate; } public void setValidate(boolean validate) { this.validate = validate; } public String[] getAttachFileNames() { return this.attachFileNames; } public void setAttachFileNames(String[] fileNames) { this.attachFileNames = fileNames; } public String getFromAddress() { return this.fromAddress; } public void setFromAddress(String fromAddress) { this.fromAddress = fromAddress; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public String getToAddress() { return this.toAddress; } public void setToAddress(String toAddress) { this.toAddress = toAddress; } public String getUserName() { return this.userName; } public void setUserName(String userName) { this.userName = userName; } public String getSubject() { return this.subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return this.content; } public void setContent(String textContent) { this.content = textContent; } }
(二)發送郵件時的身份驗證器函數
package com.yoki.util.mail; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; public class MailAuthenticator extends Authenticator { /** 用戶帳號 */ private String userName = null; /** 用戶口令 */ private String password = null; /** * @param userName * @param password */ public MailAuthenticator(String userName, String password) { this.userName = userName; this.password = password; } /** * 身份驗證 * @return */ protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } }
(三)郵件發送器測試
package com.yoki.util.mail; import java.util.Date; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Address; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.Message.RecipientType; import javax.mail.Multipart; 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; import javax.mail.internet.MimeUtility; public class MailSender { /** * 以文本格式發送郵件 * @param mailInfo 待發送郵件的信息 */ public boolean sendTextMail(MailSenderInfo mailInfo) throws Exception { // 判斷是否須要身份認證 MyAuthenticator authenticator = null; Properties props = mailInfo.getProperties(); if (mailInfo.isValidate()) { // 若是須要身份認證,則建立一個密碼驗證器 authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); } // 根據郵件會話屬性和密碼驗證器構造一個發送郵件的session Session sendMailSession = Session.getInstance(props, authenticator); // 根據session建立一個郵件消息 Message mailMessage = new MimeMessage(sendMailSession); // 建立郵件發送者地址 Address from = new InternetAddress(mailInfo.getFromAddress()); // 設置郵件消息的發送者 mailMessage.setFrom(from); // 建立郵件的接收者地址,並設置到郵件消息中 Address to = new InternetAddress(mailInfo.getToAddress()); mailMessage.setRecipient(Message.RecipientType.TO, to); // 設置郵件消息的主題 mailMessage.setSubject(mailInfo.getSubject()); // 設置郵件消息發送的時間 mailMessage.setSentDate(new Date()); // MimeMultipart類是一個容器類,包含MimeBodyPart類型的對象 Multipart mainPart = new MimeMultipart(); MimeBodyPart mbpContent = new MimeBodyPart(); // 設置郵件消息的主要內容 String mailContent = mailInfo.getContent(); mbpContent.setText(mailContent); mainPart.addBodyPart(mbpContent); // 添加附件 if (mailInfo.getAttachFileNames().length != 0){ String[] arrayOfString; int j = (arrayOfString = mailInfo.getAttachFileNames()).length; for (int i = 0; i < j; ++i) { String attachFile = arrayOfString[i]; MimeBodyPart mbpart = new MimeBodyPart(); FileDataSource fds = new FileDataSource(attachFile); // 獲得數據源 mbpart.setDataHandler(new DataHandler(fds)); // 獲得附件自己並放入BodyPart mbpart.setFileName(MimeUtility.encodeText(fds.getName())); // 獲得文件名並編碼(防止中文文件名亂碼)一樣放入BodyPart mainPart.addBodyPart(mbpart); } } mailMessage.setContent(mainPart); // 發送郵件 Transport.send(mailMessage); logBefore(this.logger, "發送成功!"); return true; } /** * 以HTML格式發送郵件 * @param mailInfo 待發送郵件的信息 */ public boolean sendHtmlMail(MailSenderInfo mailInfo) throws Exception { // 判斷是否須要身份認證 MyAuthenticator authenticator = null; Properties pro = mailInfo.getProperties(); // 若是須要身份認證,則建立一個密碼驗證器 if (mailInfo.isValidate()) { authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); } // 根據郵件會話屬性和密碼驗證器構造一個發送郵件的session Session sendMailSession = Session.getDefaultInstance(pro, authenticator); // 根據session建立一個郵件消息 Message mailMessage = new MimeMessage(sendMailSession); // 建立郵件發送者地址 Address from = new InternetAddress(mailInfo.getFromAddress()); // 設置郵件消息的發送者 mailMessage.setFrom(from); // 建立郵件的接收者地址,並設置到郵件消息中 Address to = new InternetAddress(mailInfo.getToAddress()); // Message.RecipientType.TO屬性表示接收者的類型爲TO mailMessage.setRecipient(Message.RecipientType.TO, to); // 設置郵件消息的主題 mailMessage.setSubject(mailInfo.getSubject()); // 設置郵件消息發送的時間 mailMessage.setSentDate(new Date()); // MiniMultipart類是一個容器類,包含MimeBodyPart類型的對象 Multipart mainPart = new MimeMultipart(); // 建立一個包含HTML內容的MimeBodyPart BodyPart html = new MimeBodyPart(); // 設置HTML內容 html.setContent(mailInfo.getContent(), "text/html; charset=utf-8"); mainPart.addBodyPart(html); // 添加附件 if (mailInfo.getAttachFileNames().length != 0) { String[] arrayOfString; int j = (arrayOfString = mailInfo.getAttachFileNames()).length; for (int i = 0; i < j; ++i) { String attachFile = arrayOfString[i]; html = new MimeBodyPart(); FileDataSource fds = new FileDataSource(attachFile); // 獲得數據源 html.setDataHandler(new DataHandler(fds)); // 獲得附件自己並放入BodyPart html.setFileName(MimeUtility.encodeText(fds.getName())); // 獲得文件名並編碼(防止中文文件名亂碼)一樣放入BodyPart mainPart.addBodyPart(html); } } // 將MimeMultipart對象設置爲郵件內容 mailMessage.setContent(mainPart); // 發送郵件 Transport.send(mailMessage); logBefore(this.logger, "發送成功!"); return true; } /** *@param SMTP 郵件服務器 *@param PORT 端口 *@param EMAIL 發送方郵箱帳號 *@param PAW 發送方郵箱密碼 *@param toEMAIL 接收方郵箱帳號 *@param TITLE 標題 *@param CONTENT 內容 *@param FJ 附件 *@param TYPE 1:文本格式;2:HTML格式 */ public static void sendEmail(String SMTP, String PORT, String EMAIL, String PAW, String toEMAIL, String TITLE, String CONTENT, String[] FJ, String TYPE) throws Exception { // 設置郵件信息 MailSenderInfo mailInfo = new MailSenderInfo(); mailInfo.setMailServerHost(SMTP); mailInfo.setMailServerPort(PORT); mailInfo.setValidate(true); mailInfo.setUserName(EMAIL); mailInfo.setPassword(PAW); mailInfo.setFromAddress(EMAIL); mailInfo.setToAddress(toEMAIL); mailInfo.setSubject(TITLE); mailInfo.setContent(CONTENT); mailInfo.setAttachFileNames(FJ); // 發送郵件 MailSender sms = new MailSender(); if ("1".equals(TYPE)) sms.sendTextMail(mailInfo); else sms.sendHtmlMail(mailInfo); } public static void main(String[] args) { MailSenderInfo mailInfo = new MailSenderInfo(); mailInfo.setMailServerHost("smtp.qq.com"); mailInfo.setMailServerPort("25"); mailInfo.setValidate(true); mailInfo.setUserName("1@qq.com"); mailInfo.setPassword("123"); mailInfo.setFromAddress("1@qq.com"); mailInfo.setToAddress("3@qq.com"); mailInfo.setSubject("設置郵箱標題"); mailInfo.setContent("設置郵箱內容"); MailSender sms = new MailSender(); // sms.sendTextMail(mailInfo);//發送文體格式 // sms.sendHtmlMail(mailInfo);//發送HTML格式 } }
(四)原本能夠直接按照上面main中的形式進行郵件的發送,可是若是在你的代碼中多處都使用了郵件發送,那麼這樣寫是否是太過繁雜了,一點都不簡潔。爲了方便管理,減小代碼的修改,首先,咱們須要新建一個配置文件,如:EMAIL.txt,目錄能夠是WebRoot下,內容:優化
發件服務器地址,yoki,端口,yoki,發送郵箱,yoki,密碼
示例:this
smtp.qiye.163.com,yoki,25,yoki,1@hh.com,yoki,123
其中,yoki只是一個分割字符串,後面讀取文件時用到,你們自行定義。關於發件服務器地址怎麼查看,這個我用的是Foxmail客戶端,其餘的自行百度,以下所示:編碼
(五)有了EMAIL配置文件後,最好寫個類用來存放文件路徑,方便直接使用code
package com.yoki.util; public class MyConst{ //郵箱服務器配置文件路徑 public static final String EMAIL = "config/EMAIL.txt"; }
(六)完成以上操做後,只需新建一個調用發送郵件的類便可,這裏的方法包括:統一的發送郵件的格式;文本文件讀取;郵箱驗證,以下所示:
package com.yoki.util; import java.util.Map; import java.util.HashMap; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.regex.Pattern; import java.util.regex.Matcher; import com.yoki.util.MyConst; import com.yoki.util.mail.MailSender; public class Common{ /** *EMAIL 對方郵箱,多個用;分隔開 *TITLE 標題 *CONTENT 內容 *TYPE 1=純文本 2=帶標籤 *FJ 附件 */ public static Map<String, Object> sendEmail(String EMAIL, String TITLE, String CONTENT, String[] FJ, String TYPE) throws Exception { Map map = new HashMap(); String msg = "ok"; // 發送狀態 String strEMAIL = readTxtFile(MyConst.EMAIL); // 讀取郵件配置 if ((strEMAIL != null) && (!("".equals(strEMAIL)))) { String[] strEM = strEMAIL.split(",yoki,"); if (strEM.length == 4) { EMAIL = EMAIL.replaceAll(";", ";"); EMAIL = EMAIL.replaceAll(" ", ""); String[] arrTITLE = EMAIL.split(";"); zcount = arrTITLE.length; try { for (int i = 0; i < arrTITLE.length; ++i) { if (checkEmail(arrTITLE[i])) { // 郵箱格式不對就跳過 MailSender.sendEmail(strEM[0], strEM[1], strEM[2], strEM[3], arrTITLE[i], TITLE, CONTENT, FJ, TYPE); // 調用發送郵件函數 ++count; } } msg = "ok"; } catch (Exception e) { logger.error(e.toString(), e); } } else { msg = "error"; } } else { msg = "error"; } map.put("msg", msg); return map; } /** *讀取txt的單行內容 *fileP 文件路徑 */ public static String readTxtFile(String fileP){ try{ String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")) + "../../"; filePath = filePath.replaceAll("file:/", ""); filePath = filePath.replaceAll("%20", " "); filePath = filePath.trim() + fileP.trim(); if (filePath.indexOf(":") != 1) filePath = File.separator + filePath; String encoding = "utf-8"; File file = new File(filePath); if ((file.isFile()) && (file.exists())) { // 判斷文件是否存在 InputStreamReader read = new InputStreamReader( new FileInputStream(file), encoding); // 考慮到編碼格式 BufferedReader bufferedReader = new BufferedReader(read); String lineTxt = null; while ((lineTxt = bufferedReader.readLine()) != null){ return lineTxt; } read.close(); }else System.out.println("找不到指定的文件,查看此路徑是否正確:" + filePath); }catch (Exception e){ System.out.println("讀取文件內容出錯"); } return ""; } /** *驗證郵箱 */ public static boolean checkEmail(String email){ boolean flag = false; try{ String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; Pattern regex = Pattern.compile(check); Matcher matcher = regex.matcher(email); flag = matcher.matches(); }catch(Exception e){ flag = false; } return flag; } }
(七)好了,全部的準備工做都完成了,下面就是調用了,讓咱們看看如何方便的調用吧
System.out.println("-------- 開始發送郵件任務 ---------"); String[] fj = {"D:\\doc\\模板1.xls"}; Common.sendEmail("123@qq.com","附件發送測試","本次發送的是測試文件,請接收!",fj,"2"); System.out.println("-------- 結束髮送郵件任務 ---------");
這裏,附件能夠有多個,用逗號分開便可。
以上就是一個超級方便、簡潔的郵件發送,是否是很簡單啊,調用只要兩行代碼就搞定了,哈哈 O(∩_∩)O。