Java郵件發送:帶附件 or 不帶附件 is nothing

    昨天正好要用郵件發送的功能,順便看了下具體的實現,網上的版本不少,下面是我本身以爲高可用的一個版本,很是好用,並進行總結,優化了,你們能夠拿來直接使用哦。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。

相關文章
相關標籤/搜索