1. 程式人生 > 程式設計 >Java Mail郵件傳送如何實現簡單封裝

Java Mail郵件傳送如何實現簡單封裝

首先每次傳送需要配置的東西很多,包括髮件人的郵箱和密碼、smtp伺服器和SMTP埠號等資訊。其次,沒有將傳送和郵件內容相分離。按照單一職責原則,應該有且僅有一個原因引起類的變更[1]。最後一個問題是,我們的程式碼不僅自己用,也很可能讓別人呼叫。別人呼叫的時候不想去了解郵件傳送的細節,呼叫的人只想傳儘量少的引數獲得預期的效果。因此讓Demo變成可以使用的程式碼需要我們重新設計程式碼的結構。

從Demo中我們可以抽象出兩種型別的POJO,也就是發件人和郵件。你可能會問收件人怎麼辦?收件人可以跟郵件POJO放在一起嗎?

仔細思考下我們就知道,郵件和收件人應該是分開的。因為如果郵件和收件人放在一起,那麼就意味著我的一封郵件只能傳送給特定的人了,而實際上我們會把相同的郵件傳送給不同的收件人。因此收件人只要作為傳送時的引數就可以了。

1.發件人POJO

/**
 * @Title: MailAuthenticator
 * @author: ykgao
 * @description: 
 * @date: 2017-10-11 下午04:55:37
 */
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
 
/**
 * 伺服器郵箱登入驗證
 * 
 * @author MZULE
 * 
 */
public class MailAuthenticator extends Authenticator {
 
  /**
   * 使用者名稱(登入郵箱)
   */
  private String username;
  /**
   * 密碼
   */
  private String password;
 
  /**
   * 初始化郵箱和密碼
   * 
   * @param username 郵箱
   * @param password 密碼
   */
  public MailAuthenticator(String username,String password) {
  this.username = username;
  this.password = password;
  }
 
  String getPassword() {
  return password;
  }
 
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
  return new PasswordAuthentication(username,password);
  }
 
  String getUsername() {
  return username;
  }
 
  public void setPassword(String password) {
  this.password = password;
  }
 
  public void setUsername(String username) {
  this.username = username;
  }
 
}

2.郵件POJO

用於儲存郵件主題和內容。

/**
 * @Title: SimpleMail
 * @author: ykgao
 * @description:
 * @date: 2017-10-11 下午04:56:27
 */
public class SimpleMail {
	/** 郵件主題 */
	public String Subject;

	/** 郵件內容 */
	public String Content;

	/**
	 * @return the subject
	 */
	public String getSubject() {
		return Subject;
	}

	/**
	 * @param subject
	 *      the subject to set
	 */
	public void setSubject(String subject) {
		Subject = subject;
	}

	/**
	 * @return the content
	 */
	public String getContent() {
		return Content;
	}

	/**
	 * @param content
	 *      the content to set
	 */
	public void setContent(String content) {
		Content = content;
	}

}

3.郵件傳送

設計好了POJO,我們現在需要當然是傳送郵件了。在Demo中我們需要配置SMTP伺服器,但是我們使用郵箱傳送郵件的時候並不需要填寫SMTP伺服器。其實SMTP伺服器大多數的格式是:smtp.emailType.com。此處emailType 就是你的郵箱型別也就是@後面跟的名稱。比如163郵箱就是163。不過這個方法也不是萬能的,因為outlook郵箱的smtp伺服器就不是這個格式,而是smtp-mail.outlook.com ,所以我單獨為outlook郵箱寫了個例外。

我們還需要群分郵件的功能。這個設計起來很容易,只需要一個單人傳送的過載方法,其收件人的引數可以是一個List。
為了減少介面的引數個數,我們把SMTP埠預設為587。

import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;
import javaMailDevelopment.SimpleMail;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

import com.sun.mail.util.MailSSLSocketFactory;

/**
 * @Title: SimpleMailSender
 * @author: ykgao
 * @description: 郵件傳送器
 * @date: 2017-10-11 下午04:54:50
 */

public class SimpleMailSender {

	/**
	 * 傳送郵件的props檔案
	 */
	private final transient Properties props = System.getProperties();
	/**
	 * 郵件伺服器登入驗證
	 */
	private transient MailAuthenticator authenticator;

	/**
	 * 郵箱session
	 */
	private transient Session session;

	/**
	 * 初始化郵件傳送器
	 * 
	 * @param smtpHostName
	 *      SMTP郵件伺服器地址
	 * @param username
	 *      傳送郵件的使用者名稱(地址)
	 * @param password
	 *      傳送郵件的密碼
	 */
	public SimpleMailSender(final String smtpHostName,final String username,final String password) {
		init(username,password,smtpHostName);
	}

	/**
	 * 初始化郵件傳送器
	 * 
	 * @param username
	 *      傳送郵件的使用者名稱(地址),並以此解析SMTP伺服器地址
	 * @param password
	 *      傳送郵件的密碼
	 */
	public SimpleMailSender(final String username,final String password) {
		// 通過郵箱地址解析出smtp伺服器,對大多數郵箱都管用
		String smtpHostName = "smtp." + username.split("@")[1];
		if (username.split("@")[1].equals("outlook.com")) {
			smtpHostName = "smtp-mail.outlook.com";
		}
		init(username,smtpHostName);

	}

	/**
	 * 初始化
	 * 
	 * @param username
	 *      傳送郵件的使用者名稱(地址)
	 * @param password
	 *      密碼
	 * @param smtpHostName
	 *      SMTP主機地址
	 */
	private void init(String username,String password,String smtpHostName) {
		// 初始化props
		props.setProperty("mail.transport.protocol","smtp"); // 使用的協議(JavaMail規範要求)
		props.setProperty("mail.smtp.host",smtpHostName); // 發件人的郵箱的 SMTP 伺服器地址
		props.setProperty("mail.smtp.auth","true"); // 需要請求認證
		final String smtpPort = "587";
		props.setProperty("mail.smtp.port",smtpPort);
		// props.setProperty("mail.smtp.socketFactory.class",// "javax.net.ssl.SSLSocketFactory");
		props.setProperty("mail.smtp.socketFactory.fallback","false");
		props.setProperty("mail.smtp.starttls.enable","true");
		props.setProperty("mail.smtp.socketFactory.port",smtpPort);

		// 驗證
		authenticator = new MailAuthenticator(username,password);
		// 建立session
		session = Session.getInstance(props,authenticator);
		session.setDebug(true);
	}

	/**
	 * 傳送郵件
	 * 
	 * @param recipient
	 *      收件人郵箱地址
	 * @param subject
	 *      郵件主題
	 * @param content
	 *      郵件內容
	 * @throws AddressException
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
	public void send(String recipient,String subject,Object content) throws Exception {
		// 建立mime型別郵件
		final MimeMessage message = new MimeMessage(session);
		// 設定發信人
		message.setFrom(new InternetAddress(authenticator.getUsername()));
		// 設定收件人
		message.setRecipient(RecipientType.TO,new InternetAddress(recipient));
		// 設定主題
		message.setSubject(subject);
		// 設定郵件內容
		message.setContent(content.toString(),"text/html;charset=utf-8");
		// 傳送
		Transport.send(message);
	}

	/**
	 * 群發郵件
	 * 
	 * @param recipients
	 *      收件人們
	 * @param subject
	 *      主題
	 * @param content
	 *      內容
	 * @throws AddressException
	 * @throws MessagingException
	 */
	public void send(List<String> recipients,Object content)
			throws AddressException,MessagingException {
		// 建立mime型別郵件
		final MimeMessage message = new MimeMessage(session);
		// 設定發信人
		message.setFrom(new InternetAddress(authenticator.getUsername()));
		// 設定收件人們
		final int num = recipients.size();
		InternetAddress[] addresses = new InternetAddress[num];
		for (int i = 0; i < num; i++) {
			addresses[i] = new InternetAddress(recipients.get(i));
		}
		message.setRecipients(RecipientType.TO,addresses);
		// 設定主題
		message.setSubject(subject);
		// 設定郵件內容
		message.setContent(content.toString(),"text/html;charset=utf-8");
		// 傳送
		Transport.send(message);
	}

	/**
	 * 傳送郵件
	 * 
	 * @param recipient
	 *      收件人郵箱地址 @param mail 郵件物件 @throws AddressException @throws
	 *      MessagingException @throws
	 */
	public void send(String recipient,SimpleMail mail) throws Exception {
		send(recipient,mail.getSubject(),mail.getContent());
	}

	/**
	 * 群發郵件
	 * 
	 * @param recipients
	 *      收件人們
	 * @param mail
	 *      郵件物件
	 * @throws AddressException
	 * @throws MessagingException
	 */
	public void send(List<String> recipients,SimpleMail mail) throws AddressException,MessagingException {
		send(recipients,mail.getContent());
	}

}

4.測試程式碼

程式碼寫完了,現在需要測試下程式碼是否可行。

import java.util.ArrayList;
import java.util.List;

/**
 * @Title: testMail
 * @author: ykgao
 * @description: 
 * @date: 2017-10-11 下午02:13:02
 *
 */

public class testMail {
	public static void main(String[] args) throws Exception {
    /** 建立一個郵件傳送者*/
		SimpleMailSender simpleMailSeJava Mail 郵件傳送簡單封裝 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。